diff options
| author | Patrick | 2026-05-08 02:12:39 +0200 |
|---|---|---|
| committer | Patrick | 2026-05-08 02:12:39 +0200 |
| commit | 6eabc8b45aaad9ca4d5d49311a4bac2f4aefeb11 (patch) | |
| tree | 1c982c1ad0329472dc4a41249f8d14eecbb89d73 /src/main.zig | |
| parent | aa9baa0c9d3accba27c2d659ff4f430e7d470232 (diff) | |
| download | zhttpws-6eabc8b45aaad9ca4d5d49311a4bac2f4aefeb11.tar.gz zhttpws-6eabc8b45aaad9ca4d5d49311a4bac2f4aefeb11.zip | |
add multiplayer
Diffstat (limited to 'src/main.zig')
| -rw-r--r-- | src/main.zig | 68 |
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", .{}); } |
