1 module app; 2 3 import std.file : read; 4 import std.json : JSONValue; 5 import std.regex : ctRegex; 6 7 import lighttp; 8 9 void main(string[] args) { 10 11 auto server = new Server(); 12 server.host("0.0.0.0"); 13 server.host("::"); 14 server.router.add(new Chat()); 15 server.run(); 16 17 } 18 19 class Chat { 20 21 @Get("") Resource index; 22 23 private Room[string] rooms; 24 25 this() { 26 this.index = new CachedResource("text/html", read("res/chat.html")); 27 } 28 29 @Get(`room`, `([a-z0-9]{1,16})@([a-zA-Z0-9_]{1,32})`) class Client : WebSocket { 30 31 private static uint _id = 0; 32 33 public uint id; 34 public string ip; 35 public string name; 36 private Room* room; 37 38 void onConnect(ServerRequest request, string room, string name) { 39 this.id = _id++; 40 this.ip = request.address.toString(); 41 this.name = name; 42 if(room !in rooms) rooms[room] = new Room(); 43 this.room = room in rooms; 44 this.room.add(this); 45 } 46 47 override void onClose() { 48 this.room.remove(this); 49 } 50 51 override void onReceive(ubyte[] data) { 52 this.room.broadcast(JSONValue(["type": JSONValue("message"), "sender": JSONValue(this.id), "message": JSONValue(cast(string)data)])); 53 } 54 55 } 56 57 } 58 59 class Room { 60 61 Chat.Client[uint] clients; 62 63 void add(Chat.Client client) { 64 // send current clients to the new client 65 if(this.clients.length) { 66 JSONValue[] clients; 67 foreach(c ; this.clients) { 68 clients ~= JSONValue(["id": JSONValue(c.id), "ip": JSONValue(c.ip), "name": JSONValue(c.name)]); 69 } 70 client.send(JSONValue(["type": JSONValue("list"), "list": JSONValue(clients)]).toString()); 71 } 72 // add to list and send new client to other clients 73 this.clients[client.id] = client; 74 this.broadcast(JSONValue(["type": JSONValue("add"), "id": JSONValue(client.id), "ip": JSONValue(client.ip), "name": JSONValue(client.name)])); 75 } 76 77 void remove(Chat.Client client) { 78 // remove client and broadcast message 79 this.clients.remove(client.id); 80 this.broadcast(JSONValue(["type": JSONValue("remove"), "id": JSONValue(client.id)])); 81 } 82 83 void broadcast(JSONValue json) { 84 string message = json.toString(); 85 foreach(client ; this.clients) client.send(message); 86 } 87 88 }