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 }