Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
81
Task/Chat-server/Prolog/chat-server.pro
Normal file
81
Task/Chat-server/Prolog/chat-server.pro
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
:- initialization chat_server(5000).
|
||||
|
||||
chat_server(Port) :-
|
||||
tcp_socket(Socket),
|
||||
tcp_bind(Socket, Port),
|
||||
tcp_listen(Socket, 5),
|
||||
tcp_open_socket(Socket, AcceptFd, _),
|
||||
dispatch(AcceptFd).
|
||||
|
||||
dispatch(AcceptFd) :-
|
||||
tcp_accept(AcceptFd, Socket, _),
|
||||
thread_create(process_client(Socket, _), _, [detached(true)]),
|
||||
dispatch(AcceptFd).
|
||||
|
||||
process_client(Socket, _) :-
|
||||
setup_call_cleanup(
|
||||
tcp_open_socket(Socket, Str),
|
||||
handle_connection(Str),
|
||||
close(Str)).
|
||||
|
||||
% a connection was made, get the username and add the streams so the
|
||||
% client can be broadcast to.
|
||||
handle_connection(Str) :-
|
||||
send_msg(Str, msg_welcome, []),
|
||||
repeat,
|
||||
send_msg(Str, msg_username, []),
|
||||
read_line_to_string(Str, Name),
|
||||
connect_user(Name, Str), !.
|
||||
|
||||
% connections are stored here
|
||||
:- dynamic(connected/2).
|
||||
|
||||
connect_user(Name, Str) :-
|
||||
connected(Name, _),
|
||||
send_msg(Str, msg_username_taken, []),
|
||||
fail.
|
||||
connect_user(Name, Str) :-
|
||||
\+ connected(Name, _),
|
||||
send_msg(Str, msg_welcome_name, Name),
|
||||
|
||||
% make sure that the connection is removed when the client leaves.
|
||||
setup_call_cleanup(
|
||||
assert(connected(Name, Str)),
|
||||
(
|
||||
broadcast(Name, msg_joined, Name),
|
||||
chat_loop(Name, Str), !,
|
||||
broadcast(Name, msg_left, Name)
|
||||
),
|
||||
retractall(connected(Name, _))
|
||||
).
|
||||
|
||||
% wait for a line to be sent then broadcast to the rest of the clients
|
||||
% finish this goal when the client disconnects (end of stream)
|
||||
chat_loop(Name, Str) :-
|
||||
read_line_to_string(Str, S),
|
||||
dif(S, end_of_file),
|
||||
broadcast(Name, msg_by_user, [Name, S]),
|
||||
chat_loop(Name, Str).
|
||||
chat_loop(_, Str) :- at_end_of_stream(Str).
|
||||
|
||||
% send a message to all connected clients except Name (the sender)
|
||||
broadcast(Name, Msg, Params) :-
|
||||
forall(
|
||||
(connected(N, Str), dif(N, Name)),
|
||||
(send_msg(Str, Msg, Params), send_msg(Str, msg_new_line, []))
|
||||
).
|
||||
|
||||
send_msg(St, MsgConst, Params) :-
|
||||
call(MsgConst, Msg),
|
||||
format(St, Msg, Params),
|
||||
flush_output(St).
|
||||
|
||||
% constants for the various message types that are sent
|
||||
msg_welcome('Welcome to Chatalot\n\r').
|
||||
msg_username('Please enter your nickname: ').
|
||||
msg_welcome_name('Welcome ~p\n\r').
|
||||
msg_joined(' -- "~w" has joined the chat --').
|
||||
msg_left(' -- "~w" has left the chat. --').
|
||||
msg_username_taken('That username is already taken, choose another\n\r').
|
||||
msg_new_line('\n\r').
|
||||
msg_by_user('~w> ~w').
|
||||
Loading…
Add table
Add a link
Reference in a new issue