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(new Chat());
12 	server.host("0.0.0.0", 80);
13 	
14 	while(true) server.eventLoop.loop();
15 
16 }
17 
18 class Chat : Router {
19 
20 	@Get("") Resource index;
21 	
22 	private Room[string] rooms;
23 	
24 	this() {
25 		this.index = new CachedResource("text/html", read("res/chat.html"));
26 	}
27 	
28 	@Get(`room`, `([a-z0-9]{2,16})@([a-zA-Z0-9]{3,16})`) class Client : WebSocket {
29 	
30 		private static uint _id = 0;
31 	
32 		public uint id;
33 		public string name;
34 		private Room* room;
35 		
36 		void onConnect(NetworkAddress address, string room, string name) {
37 			this.id = _id++;
38 			this.name = name;
39 			if(room !in rooms) rooms[room] = new Room();
40 			this.room = room in rooms;
41 			this.room.add(this);
42 		}
43 		
44 		override void onClose() {
45 			this.room.remove(this);
46 		}
47 		
48 		override void onReceive(ubyte[] data) {
49 			this.room.broadcast(this, JSONValue(["type": "message", "message": cast(string)data]));
50 		}
51 	
52 	}
53 
54 }
55 
56 class Room {
57 
58 	Chat.Client[uint] clients;
59 	
60 	void add(Chat.Client client) {
61 		this.clients[client.id] = client;
62 		this.broadcast(client, JSONValue(["type": "join"]));
63 	}
64 	
65 	void remove(Chat.Client client) {
66 		this.clients.remove(client.id);
67 		this.broadcast(client, JSONValue(["type": "leave"]));
68 	}
69 	
70 	void broadcast(Chat.Client client, JSONValue json) {
71 		json["user"] = ["id": JSONValue(client.id), "name": JSONValue(client.name)];
72 		string message = json.toString();
73 		foreach(client ; this.clients) client.send(message);
74 	}
75 
76 }