karlseguin / websocket.zig

A websocket implementation for zig
MIT License
283 stars 25 forks source link

struct 'os.windows.ws2_32.POLL' has no member named 'IN' #16

Closed hajsf closed 11 months ago

hajsf commented 11 months ago

Hi, I'm trying to run the my code as Windows 11, but I got the error below:

PS D:\from_ubuntu\zig> zig run server.zig
websocket.zig\src\server.zig:298:20: error: struct 'os.windows.ws2_32.POLL' has no member named 'IN'
  .events = os.POLL.IN,
            ~~~~~~~^~~
C:\zig-windows-x86_64-0.11.0\zig\lib\std\os\windows\ws2_32.zig:844:18: note: struct declared here
pub const POLL = struct {
                 ^~~~~~
karlseguin commented 11 months ago

On the latest master, I replaced the use of os.poll with setsockopt.

I don't have access to windows, but with this latest change, I was able to cross compile a windows binary.

However, the websocket.Client code is still using os.poll, so you won't be able to use any of that code.

hajsf commented 11 months ago

However, the websocket.Client code is still using os.poll

Can it be fixed?

The server part is fine now, I was able to coomunicate with it from JavaScript:

PS D:\ubuntu\zig> zig run server.zig
debug: Ping

But the client part looks need some more fixes, I got the below:

PS D:\ubuntu\zig> zig run ws.zig
websocket.zig\src\client.zig:261:22: error: struct 'os.windows.ws2_32.POLL' has no member named 'IN'
    .events = os.POLL.IN,
              ~~~~~~~^~~
C:\zig-windows-x86_64-0.11.0\zig\lib\std\os\windows\ws2_32.zig:844:18: note: struct declared here
pub const POLL = struct {
                 ^~~~~~
referenced by:
    connect: websocket.zig\src\client.zig:50:23
    connect: websocket.zig\src\websocket.zig:9:27
    remaining reference traces hidden; use '-freference-trace' to see all reference traces
C:\zig-windows-x86_64-0.11.0\zig\lib\std\c.zig:354:12: error: dependency on libc must be explicitly specified in the build command
pub extern "c" fn poll(fds: [*]c.pollfd, nfds: c.nfds_t, timeout: c_int) c_int;
           ^~~
karlseguin commented 11 months ago

The client compiles on windows for me now (Check out the latest master)

hajsf commented 11 months ago

Thanks, it is working fine weith me now:

image

The codes used are:

//server.zig
const std=@import("std");
const websocket = @import("./websocket.zig/src/websocket.zig");
const Conn = websocket.Conn;
const Message = websocket.Message;
const Handshake = websocket.Handshake;

// Define a struct for "global" data passed into your websocket handler
const Context = struct {
};

pub fn main() !void {
    var general_purpose_allocator = std.heap.GeneralPurposeAllocator(.{}){};
    const allocator = general_purpose_allocator.allocator();

    // this is the instance of your "global" struct to pass into your handlers
    var context = Context{}; 

    try websocket.listen(Handler, allocator, &context, .{
        .port = 9223,
        .max_headers = 10,
        .address = "127.0.0.1",
    });
}

const Handler = struct {
    conn: *Conn,
    context: *Context,

    pub fn init(h: Handshake, conn: *Conn, context: *Context) !Handler {
        // `h` contains the initial websocket "handshake" request
        // It can be used to apply application-specific logic to verify / allow
        // the connection (e.g. valid url, query string parameters, or headers)

        _ = h; // we're not using this in our simple case

        return Handler{
            .conn = conn,
            .context = context,
        };
    }

    // optional hook that, if present, will be called after initialization is complete
    pub fn afterInit(self: *Handler) !void {
        _ = self;}

    pub fn handle(self: *Handler, message: Message) !void {
        const data = message.data;
        std.log.debug("{s}", .{data});
        try self.conn.write(data); // echo the message back
    }

    // called whenever the connection is closed, can do some cleanup in here
    pub fn close(_: *Handler) void {}
};

And

//ws.zig
const std = @import("std");
const websocket = @import("./websocket.zig/src/websocket.zig");

const Handler = struct {
    client: websocket.Client,

    pub fn init(allocator: std.mem.Allocator, host: []const u8, port: u16) !Handler {
        return .{
            .client = try websocket.connect(allocator, host, port, .{}),
        };
    }

    pub fn deinit(self: *Handler) void {
        self.client.deinit();
    }

    pub fn connect(self: *Handler, path: []const u8) !void {
        try self.client.handshake(path, .{.timeout_ms = 5000});
        const thread = try self.client.readLoopInNewThread(self);
        thread.detach();
    }

    pub fn handle(_: Handler, message: websocket.Message) !void {
        const data = message.data;
        std.debug.print("CLIENT GOT: {s}\n", .{data});
    }

    pub fn write(self: *Handler, data: []u8) !void {
        return self.client.write(data);
    }

    pub fn close(_: Handler) void {}

};

pub fn main() !void {
    var general_purpose_allocator = std.heap.GeneralPurposeAllocator(.{}){};
    const allocator = general_purpose_allocator.allocator();

    var handler = try Handler.init(allocator, "127.0.0.1", 9223);
    defer handler.deinit();
    // spins up a thread to listen to new messages
    try handler.connect("/");

    var data = try allocator.dupe(u8, "hello world");
    try handler.write(data);

    data = try allocator.dupe(u8, "hello Zig");
    try handler.write(data);
    data = try allocator.dupe(u8, "hello Hasan");
    try handler.write(data);

    // without this, we'll exit immediately without having time to receive the
    // echo'd message from the server
    std.time.sleep(std.time.ns_per_s);
}