50 lines
1.6 KiB
Plaintext
50 lines
1.6 KiB
Plaintext
const PORT=23;
|
|
|
|
var users=Dictionary(); // ( handle:socket, ...)
|
|
pipe:=Thread.Pipe(); // how server tells thread to connect to user
|
|
|
|
fcn accept(pipe){ // a thread waiting for the server to send a socket
|
|
while(socket:=pipe.read()){
|
|
println("Somebody is connecting ...");
|
|
socket.read(); // telnet stuff
|
|
while(True){ // get credentials
|
|
reg name;
|
|
socket.write("Your handle: "); // bottle neck
|
|
try{ name = socket.read().text.strip() } catch(IOError){ continue }
|
|
if(users.holds(name)) socket.write("Handle is already in use.\n");
|
|
else if(name){
|
|
users[name] = socket;
|
|
chat.launch(name,socket); // thread
|
|
broadcast(name, "+++ %s arrived +++".fmt(name));
|
|
break; // wait for next connection
|
|
}
|
|
}//while
|
|
}//while
|
|
}.launch(pipe); // thread
|
|
|
|
fcn chat(name,socket){ // a thread, one per user
|
|
try{
|
|
socket.write("^D to disconnect\n");
|
|
while(True){
|
|
message:=socket.read().text.strip();
|
|
if(message=="\xff\xec") break; // ^D to disconnect.
|
|
broadcast(name, "%s> %s".fmt(name,message));
|
|
}
|
|
}catch{} // eg socket pukes
|
|
users.del(name); socket.close();
|
|
broadcast(name, "--- %s leaves ---".fmt(name));
|
|
}
|
|
|
|
// Send a message to all users from the given name.
|
|
fcn broadcast(name, message){ // called from user thread
|
|
println(message); // log message to server console
|
|
users.pump(Void,'wrap([(toName,socket)]){
|
|
if(toName != name) try{ socket.write(message + "\n") } catch(IOError){}
|
|
});
|
|
}
|
|
|
|
// Set up the server socket.
|
|
server:=Network.TCPServerSocket.open(PORT);
|
|
println("Listening on %s:%s".fmt(server.hostname,server.port));
|
|
server.listen(pipe); // Main event loop
|