Thomvanoorschot/async_zocket
This repository contains a basic, non-blocking WebSocket client written in the Zig programming language. It leverages the xev event loop for asynchron...
main.tar.gz
AsyncZocket is a comprehensive WebSocket library for the Zig programming language, providing both client and server implementations. Built on the xev
event loop library for high-performance asynchronous I/O operations, it offers a robust foundation for real-time communication applications. The library supports the full WebSocket protocol (RFC 6455) and can handle multiple concurrent connections efficiently on a single thread.
xev
for non-blocking operationsUse fetch:
zig fetch --save https://github.com/Thomvanoorschot/async_zocket/archive/main.tar.gz
Or add AsyncZocket to your build.zig.zon
:
.dependencies = .{
.async_zocket = .{
.url = "https://github.com/thomvanoorschot/async_zocket/archive/main.tar.gz",
.hash = "...", // Update with actual hash
},
},
const std = @import("std");
const AsyncZocket = @import("async_zocket");
const xev = @import("xev");
// Initialize event loop
var loop = try xev.Loop.init(.{});
defer loop.deinit();
// Define message callback
const wrapperStruct = struct {
const Self = @This();
fn read_callback(context: *anyopaque, payload: []const u8) !void {
// You can access the context by casting it to the correct type
// const self = @as(*Self, @ptrCast(context));
// self.read_callback(self.callback_context, payload);
std.log.info("read_callback: {s}\n", .{payload});
_ = context;
}
};
var ws = wrapperStruct{};
// Create and connect client
var client = try AsyncZocket.Client.init(
std.heap.page_allocator,
&loop,
.{
.host = "127.0.0.1",
.port = 8080,
.path = "/ws",
.use_tls = true
},
wrapperStruct.read_callback,
@ptrCast(&ws)
);
try client.connect();
// Send a message
try client.write("Hello, WebSocket!");
// Run event loop
try loop.run(.until_done);
const std = @import("std");
const AsyncZocket = @import("async_zocket");
const xev = @import("xev");
// Initialize event loop
var loop = try xev.Loop.init(.{});
defer loop.deinit();
// Define callbacks
const wrapperStruct = struct {
const Self = @This();
fn accept_callback(
_: ?*anyopaque,
_: *xev.Loop,
_: *xev.Completion,
cc: *ClientConnection,
) xev.CallbackAction {
cc.read();
return .rearm;
}
fn read_callback(
context: ?*anyopaque,
payload: []const u8,
) void {
_ = context;
std.log.info("read_callback: {s}", .{payload});
std.heap.page_allocator.free(payload);
}
};
var ws = wrapperStruct{};
// Create and start server
var server = try AsyncZocket.Server.init(
std.heap.page_allocator,
&loop,
.{
.host = "127.0.0.1",
.port = 8081,
.max_connections = 10,
},
@ptrCast(&ws),
wrapperStruct.accept_callback,
wrapperStruct.read_callback,
);
server.accept();
// Run event loop
try loop.run(.until_done);
Client.init()
- Initialize a new WebSocket clientclient.connect()
- Connect to the WebSocket serverclient.write()
- Send a text messageclient.read()
- Start reading incoming messagesclient.deinit()
- Clean up client resourcesServer.init()
- Initialize a new WebSocket serverserver.accept()
- Start accepting client connectionsserver.returnConnection()
- Return a closed connection to the poolserver.deinit()
- Clean up server resourcesClientConfig:
host: []const u8
- Server hostname or IP addressport: u16
- Server port numberpath: []const u8
- WebSocket endpoint pathuse_tls: bool
- Encrypts trafficServerOptions:
host: []const u8
- Server hostname or IP addressport: u16
- Server port numbermax_connections: u31
- Maximum concurrent connections (default: 1024)🚀 Production Ready - The library implements a complete WebSocket solution with both client and server capabilities.
Implemented Features:
Upcoming Features:
Contributions are welcome! Please feel free to submit pull requests, report bugs, or suggest features.
This project is licensed under the MIT License - see the LICENSE file for details.