mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-29 23:23:28 +00:00
websocket: first implementation
Signed-off-by: Francis Bouvier <francis@lightpanda.io>
This commit is contained in:
@@ -19,6 +19,8 @@
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
|
||||
const Stream = @import("handler.zig").Stream;
|
||||
|
||||
const jsruntime = @import("jsruntime");
|
||||
const Completion = jsruntime.IO.Completion;
|
||||
const AcceptError = jsruntime.IO.AcceptError;
|
||||
@@ -49,6 +51,7 @@ const MaxStdOutSize = 512; // ensure debug msg are not too long
|
||||
|
||||
pub const Ctx = struct {
|
||||
loop: *jsruntime.Loop,
|
||||
stream: ?*Stream,
|
||||
|
||||
// internal fields
|
||||
accept_socket: std.posix.socket_t,
|
||||
@@ -283,7 +286,18 @@ pub const Ctx = struct {
|
||||
|
||||
// send result
|
||||
if (!std.mem.eql(u8, res, "")) {
|
||||
return sendAsync(self, res);
|
||||
return self.send(res);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn send(self: *Ctx, msg: []const u8) !void {
|
||||
if (self.stream) |stream| {
|
||||
// if we have a stream connection, just write on it
|
||||
defer self.alloc().free(msg);
|
||||
try stream.send(msg);
|
||||
} else {
|
||||
// otherwise write asynchronously on the socket connection
|
||||
return sendAsync(self, msg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -362,7 +376,7 @@ pub const Ctx = struct {
|
||||
.{ msg_open, cdp.ContextSessionID },
|
||||
);
|
||||
|
||||
try sendAsync(ctx, s);
|
||||
try ctx.send(s);
|
||||
}
|
||||
|
||||
pub fn onInspectorResp(ctx_opaque: *anyopaque, _: u32, msg: []const u8) void {
|
||||
@@ -422,16 +436,17 @@ const Send = struct {
|
||||
|
||||
pub fn sendAsync(ctx: *Ctx, msg: []const u8) !void {
|
||||
const sd = try Send.init(ctx, msg);
|
||||
ctx.loop.io.send(*Send, sd, Send.asyncCbk, &sd.completion, ctx.conn_socket, msg);
|
||||
ctx.loop.io.send(*Send, sd, Send.asyncCbk, &sd.completion, ctx.conn_socket, sd.msg);
|
||||
}
|
||||
|
||||
// Listen
|
||||
// ------
|
||||
// Listener and handler
|
||||
// --------------------
|
||||
|
||||
pub fn listen(
|
||||
pub fn handle(
|
||||
alloc: std.mem.Allocator,
|
||||
loop: *jsruntime.Loop,
|
||||
server_socket: std.posix.socket_t,
|
||||
stream: ?*Stream,
|
||||
timeout: u64,
|
||||
) anyerror!void {
|
||||
|
||||
@@ -458,6 +473,7 @@ pub fn listen(
|
||||
// for accepting connections and receving messages
|
||||
var ctx = Ctx{
|
||||
.loop = loop,
|
||||
.stream = stream,
|
||||
.browser = &browser,
|
||||
.sessionNew = true,
|
||||
.read_buf = &read_buf,
|
||||
@@ -497,3 +513,35 @@ pub fn listen(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn setSockOpt(fd: std.posix.socket_t, level: i32, option: u32, value: c_int) !void {
|
||||
try std.posix.setsockopt(fd, level, option, &std.mem.toBytes(value));
|
||||
}
|
||||
|
||||
pub fn listen(address: std.net.Address) !std.posix.socket_t {
|
||||
|
||||
// create socket
|
||||
const flags = std.posix.SOCK.STREAM | std.posix.SOCK.CLOEXEC | std.posix.SOCK.NONBLOCK;
|
||||
const sockfd = try std.posix.socket(address.any.family, flags, std.posix.IPPROTO.TCP);
|
||||
errdefer std.posix.close(sockfd);
|
||||
|
||||
// socket options
|
||||
try setSockOpt(sockfd, std.posix.SOL.SOCKET, std.posix.SO.REUSEADDR, 1);
|
||||
if (@hasDecl(std.posix.SO, "REUSEPORT")) {
|
||||
try setSockOpt(sockfd, std.posix.SOL.SOCKET, std.posix.SO.REUSEPORT, 1);
|
||||
}
|
||||
if (builtin.target.os.tag == .linux) { // posix.TCP not available on MacOS
|
||||
// WARNING: disable Nagle's alogrithm to avoid latency issues
|
||||
try setSockOpt(sockfd, std.posix.IPPROTO.TCP, std.posix.TCP.NODELAY, 1);
|
||||
}
|
||||
|
||||
// bind & listen
|
||||
var socklen = address.getOsSockLen();
|
||||
try std.posix.bind(sockfd, &address.any, socklen);
|
||||
const kernel_backlog = 1; // default value is 128. Here we just want 1 connection
|
||||
try std.posix.listen(sockfd, kernel_backlog);
|
||||
var listen_address: std.net.Address = undefined;
|
||||
try std.posix.getsockname(sockfd, &listen_address.any, &socklen);
|
||||
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user