Chat server: Difference between revisions
Content added Content deleted
(→{{header|Go}}: small simplification, possible now with new delete function) |
(CoffeeScript) |
||
Line 91: | Line 91: | ||
end loop; |
end loop; |
||
end Chat_Server;</lang> |
end Chat_Server;</lang> |
||
=={{header|CoffeeScript}}== |
|||
This is ported from the JavaScript version. The tool js2coffee got me a mostly working version, and then I manually converted JS-style classes to CS "class class" syntax. |
|||
<lang coffeescript> |
|||
net = require("net") |
|||
sys = require("sys") |
|||
EventEmitter = require("events").EventEmitter |
|||
isNicknameLegal = (nickname) -> |
|||
return false unless nickname.replace(/[A-Za-z0-9]*/, "") is "" |
|||
for used_nick of @chatters |
|||
return false if used_nick is nickname |
|||
true |
|||
class ChatServer |
|||
constructor: -> |
|||
@chatters = {} |
|||
@server = net.createServer @handleConnection |
|||
@server.listen 1212, "localhost" |
|||
handleConnection: (connection) => |
|||
console.log "Incoming connection from " + connection.remoteAddress |
|||
connection.setEncoding "utf8" |
|||
chatter = new Chatter(connection, this) |
|||
chatter.on "chat", @handleChat |
|||
chatter.on "join", @handleJoin |
|||
chatter.on "leave", @handleLeave |
|||
handleChat: (chatter, message) => |
|||
@sendToEveryChatterExcept chatter, chatter.nickname + ": " + message |
|||
handleJoin: (chatter) => |
|||
console.log chatter.nickname + " has joined the chat." |
|||
@sendToEveryChatter chatter.nickname + " has joined the chat." |
|||
@addChatter chatter |
|||
handleLeave: (chatter) => |
|||
console.log chatter.nickname + " has left the chat." |
|||
@removeChatter chatter |
|||
@sendToEveryChatter chatter.nickname + " has left the chat." |
|||
addChatter: (chatter) => |
|||
@chatters[chatter.nickname] = chatter |
|||
removeChatter: (chatter) => |
|||
delete @chatters[chatter.nickname] |
|||
sendToEveryChatter: (data) => |
|||
for nickname of @chatters |
|||
@chatters[nickname].send data |
|||
sendToEveryChatterExcept: (chatter, data) => |
|||
for nickname of @chatters |
|||
@chatters[nickname].send data unless nickname is chatter.nickname |
|||
class Chatter extends EventEmitter |
|||
constructor: (socket, server) -> |
|||
EventEmitter.call this |
|||
@socket = socket |
|||
@server = server |
|||
@nickname = "" |
|||
@lineBuffer = new SocketLineBuffer(socket) |
|||
@lineBuffer.on "line", @handleNickname |
|||
@socket.on "close", @handleDisconnect |
|||
@send "Welcome! What is your nickname?" |
|||
handleNickname: (nickname) => |
|||
if isNicknameLegal(nickname) |
|||
@nickname = nickname |
|||
@lineBuffer.removeAllListeners "line" |
|||
@lineBuffer.on "line", @handleChat |
|||
@send "Welcome to the chat, " + nickname + "!" |
|||
@emit "join", this |
|||
else |
|||
@send "Sorry, but that nickname is not legal or is already in use!" |
|||
@send "What is your nickname?" |
|||
handleChat: (line) => |
|||
@emit "chat", this, line |
|||
handleDisconnect: => |
|||
@emit "leave", this |
|||
send: (data) => |
|||
@socket.write data + "\r\n" |
|||
class SocketLineBuffer extends EventEmitter |
|||
constructor: (socket) -> |
|||
EventEmitter.call this |
|||
@socket = socket |
|||
@buffer = "" |
|||
@socket.on "data", @handleData |
|||
handleData: (data) => |
|||
console.log "Handling data", data |
|||
i = 0 |
|||
while i < data.length |
|||
char = data.charAt(i) |
|||
@buffer += char |
|||
if char is "\n" |
|||
@buffer = @buffer.replace("\r\n", "") |
|||
@buffer = @buffer.replace("\n", "") |
|||
@emit "line", @buffer |
|||
console.log "incoming line: #{@buffer}" |
|||
@buffer = "" |
|||
i++ |
|||
server = new ChatServer() |
|||
</lang> |
|||
=={{header|Erlang}}== |
=={{header|Erlang}}== |