Gebweb chat demo
Single-room chat application demonstrating that a Gebweb
- Path
gebweb/examples/chat/main.gb- Category
- Chat
app can run both HTTP routes and WebSocket connections on the
same port, sharing a DI-injected broadcast hub.
Run:
geblang examples/chat/main.gb
Then open http://127.0.0.1:8088/ in two browser tabs and send
messages between them.
Source
import gebweb;
import gebweb.broadcast as bcast;
import io;
import json;
import web.websocket as ws;
class ChatController extends gebweb.Controller {
bcast.Hub hub;
func ChatController(bcast.Hub hub) {
parent();
this.hub = hub;
}
@Get("/")
func index(dict<string, any> request): dict<string, any> {
return this.view(request, "chat.html", {});
}
@Get("/ws")
@WebSocket
func chat(ws.Connection conn): void {
string nickname = "";
let sub = this.hub.join(conn);
try {
while (true) {
let raw = conn.readText();
if (raw == "") { break; }
let envelope = json.parse(raw) as dict<string, any>;
string kind = envelope["type"] as string;
if (kind == "hello") {
nickname = envelope["nickname"] as string;
this.hub.broadcastExcept(this.event("system",
nickname + " joined", "*"), sub);
conn.sendText(this.event("system",
"welcome, " + nickname, "*"));
continue;
}
if (kind == "msg") {
if (nickname == "") { continue; }
string body = envelope["body"] as string;
this.hub.broadcast(this.event("msg", body, nickname));
}
}
} catch (Error e) { }
this.hub.leave(sub);
if (nickname != "") {
this.hub.broadcast(this.event("system", nickname + " left", "*"));
}
conn.close();
}
func event(string kind, string body, string from): string {
return json.stringify({"type": kind, "body": body, "from": from});
}
}
let app = gebweb.app([]);
gebweb.useViews(app, "examples/chat/templates");
gebweb.registerInstance(app, bcast.Hub, bcast.newHub());
gebweb.addControllers(app, [ChatController]);
io.println("Chat demo running on http://127.0.0.1:8088");
io.println("Open the URL in two browser tabs to see messages relay.");
gebweb.serve(app, "127.0.0.1:8088");