treesummaryrefslogcommitdiff
path: root/src/main.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.zig')
-rw-r--r--src/main.zig68
1 files changed, 43 insertions, 25 deletions
diff --git a/src/main.zig b/src/main.zig
index b874ddd..3616370 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -1,17 +1,36 @@
const std = @import("std");
const Io = std.Io;
+const WebSocket = std.http.Server.WebSocket;
+
+var m = std.atomic.Mutex.unlocked;
+
+var clients: std.ArrayList(*WebSocket) = undefined;
+
+fn broadcast(sm: WebSocket.SmallMessage) void {
+ if (!m.tryLock()) return;
+ for (clients.items) |c| {
+ c.writeMessage(sm.data, sm.opcode) catch {};
+ }
+ m.unlock();
+}
+
+fn handle_websocket(alloc: std.mem.Allocator, websocket: *WebSocket) void {
+ if (!m.tryLock()) return;
+ clients.append(alloc, websocket) catch {};
+ m.unlock();
+
+ const i = clients.items.len;
+ defer _ = clients.swapRemove(i);
-fn handle_websocket(websocket: *std.http.Server.WebSocket) void {
websocket.writeMessage("welcome", .text) catch return;
while (true) {
const sm = websocket.readSmallMessage() catch break;
- std.debug.print("websocket received: {s}\n", .{sm.data});
- websocket.writeMessage(sm.data, sm.opcode) catch break;
+ broadcast(sm);
}
}
-fn handle_request(io: std.Io, stream: std.Io.net.Stream) void {
+fn handle_request(alloc: std.mem.Allocator, io: Io, stream: Io.net.Stream) void {
var recv_buffer: [999]u8 = undefined;
var send_buffer: [100]u8 = undefined;
@@ -26,27 +45,25 @@ fn handle_request(io: std.Io, stream: std.Io.net.Stream) void {
switch (req.upgradeRequested()) {
.websocket => |ws| {
- std.debug.print("ws: {s}\n", .{ws.?});
var websocket = req.respondWebSocket(.{ .key = ws.? }) catch break;
- std.debug.print("handling websocket business\n", .{});
- handle_websocket(&websocket);
- std.debug.print("done handling websocket business\n", .{});
+
+ handle_websocket(alloc, &websocket);
+ },
+ else => {
+ req.respond(
+ \\ <script>
+ \\ const socket = new WebSocket("wss://yap.ps.run");
+ \\ socket.addEventListener("open", (event) => {
+ \\ socket.send("Hello Server!");
+ \\ });
+ \\ socket.addEventListener("message", (event) => {
+ \\ console.log("Message from server ", event.data);
+ \\ });
+ \\ </script>
+ \\ <p>hallo</p>
+ , .{ .status = .ok }) catch break;
},
- else => {},
}
-
- req.respond(
- \\ <script>
- \\ const socket = new WebSocket("ws://localhost:1234");
- \\ socket.addEventListener("open", (event) => {
- \\ socket.send("Hello Server!");
- \\ });
- \\ socket.addEventListener("message", (event) => {
- \\ console.log("Message from server ", event.data);
- \\ });
- \\ </script>
- \\ <p>hallo</p>
- , .{ .status = .ok }) catch break;
}
// std.debug.print("closing http thread\n", .{});
@@ -59,6 +76,8 @@ pub fn main(init: std.process.Init) !void {
// This is appropriate for anything that lives as long as the process.
const arena: std.mem.Allocator = init.arena.allocator();
+ clients = try .initCapacity(arena, 10);
+
// Accessing command line arguments:
const args = try init.minimal.args.toSlice(arena);
for (args) |arg| {
@@ -72,8 +91,7 @@ pub fn main(init: std.process.Init) !void {
if (init.environ_map.get("PORT")) |s| {
if (std.fmt.parseInt(u16, s, 10)) |p| {
port = p;
- }
- else |e| {
+ } else |e| {
std.debug.print("{}\n", .{e});
}
}
@@ -84,7 +102,7 @@ pub fn main(init: std.process.Init) !void {
while (true) {
const stream = try net_server.accept(io);
- _ = io.async(handle_request, .{ io, stream });
+ _ = io.async(handle_request, .{ arena, io, stream });
// std.debug.print("created http thread\n", .{});
}