/** Following along the tutorial at https://vibed.org/blog/posts/a-scalable-chat-room-service-in-d More notes at https://wiki.jon.geek.nz/D Add the D apt respository in /etc/apt/sources.list.d/dlang.list: deb http://netcologne.dl.sourceforge.net/project/d-apt/ d-apt main Then get the apt key, and install the things: sudo apt-get update sudo apt-get -y --allow-unauthenticated install --reinstall d-apt-keyring sudo apt-get install dmd-bin dcd dub */ import vibe.d; final class Room { string[] messages; ManualEvent messageEvent; this() { messageEvent = createManualEvent(); } void addMessage(string nick, string message) { messages ~= nick ~ ": " ~ message; } void waitForMessage(size_t next_message) { while (messages.length <= next_message) { messageEvent.wait(); } } } final class WebChat { private Room[string] rooms; // Uses vibe.d magic method names - in this case, GET / void get() { render!("index.dt"); } // Uses vibe.d magic method names - in this case, GET /hello void getHello() { render!("hello.dt"); } // GET /room void getRoom(string room, string nick) { auto messages = getOrCreateRoom(room).messages; render!("room.dt", room, nick, messages); } // POST /room void postRoom(string room, string nick, string message) { if (message.length) getOrCreateRoom(room).addMessage(nick, message); redirect("room?room=" ~ room.urlEncode ~ "&nick=" ~ nick.urlEncode); } // /ws?room=...&nick=... void getWS(string room, string nick, scope WebSocket socket) { auto r = getOrCreateRoom(room); auto writer = runTask({ auto next_message = r.messages.length; while (socket.connected) { while (next_message < r.messages.length) { socket.send(r.messages[next_message++]); } r.waitForMessage(next_message); } }); while (socket.waitForData) { auto message = socket.receiveText(); if (message.length) { r.addMessage(nick, message); } } writer.join(); } private Room getOrCreateRoom(string room) { if (auto pr = room in rooms) return *pr; return rooms[room] = new Room; } } shared static this() { auto router = new URLRouter; router.registerWebInterface(new WebChat); // If nothing else matches, try serving it from public router.get("*", serveStaticFiles("public/")); auto settings = new HTTPServerSettings; settings.port = 8083; // settings.bindAddresses = ["::", "0.0.0.0"]; listenHTTP(settings, router); logInfo("Please open http://127.0.0.1:%d/ in your browser.".format(settings.port)); }