Mojo-Websockets: WebSocket servers and clients

Hello, I’m excited to share the mojo-websockets library for building websockets in Mojo in a similar way for those who are use to the Python websockets library.

Features

  • WebSocket Server and Client: Supports creating both WebSocket servers and clients.
  • Compatibility: API designed to be intuitive for developers familiar with the Python websockets library.
  • Sans/IO Layer: Implements a WebSocket Sans/IO layer pure Mojo and performs no I/O of its own.

The main TO-DO is the non-blocking communications support, as it’s waiting for the official Mojo async support.

Any feedback and contributions are highly appreciated!

7 Likes

Always happy to see sans-io protocol implementations!

1 Like

100%. Thanks to the Sans/IO I could add 200+ tests to check my implementation with no I/O connection at all

Unfortunately, without proper async support in Mojo, the WebSocket server is not usable. In Lightbug, at least, the HTTP connections are quick if there is no keep-alive. However, websocket connections remain active for a whole lifetime.

That’s great, good job!
There is also the autobahn websocket test suite i think :+1:

I am trying to workaround the lack of async support trying to do it using threads. This is the PR I tried: Threading version to try to serve connections in parallel by msaelices · Pull Request #2 · msaelices/mojo-websockets · GitHub

The problem is these major issues:

  1. The thread context was deleted by Mojo and I don’t know how to properly fix it. I used the mark_destroyed trickery but I don’t know if there is a better approach (it should)
  2. There is a segfault related to the CPython interpreter. Don’t know how to fix it.

Do you have any clue? Thanks in advance.

Most kinds of threading are going to break a lot of things. There’s no way to take the gil right now, so you can’t call python code. You also can’t access global variables.

I think it would be better to try to set up epoll or io_uring and take event handlers.

Thanks for the suggestion. I’ve seen there is already a io_uring library in Mojo GitHub - dmitry-salin/io_uring: The io_uring library for Mojo

I’ve just adapted it to use the latest 25.1 version: Update code to support Mojo and Max 25.1 by msaelices · Pull Request #1 · dmitry-salin/io_uring · GitHub

When/If merged, I will add it to the official max community channel so I hope @Caroline will be happy about it

2 Likes

The support of concurrent connections is already implemented in the io_uring branch. It’s blocked because of some PR for fixing the io_uring wrapper on the latest Max version, but it will be merged soon.

Thanks to @owenhilyard for the suggestion.

I run this client code, and the response is limited to 1024 characters. How can I get longer responses?

from websockets.sync.client import connect

fn send_and_receive(msg: String) raises:
    with connect("ws://127.0.0.1:8000") as client:
        client.send_text(msg)
        print(">>> ", msg)
        response = client.recv_text()
        print("<<< ", response)

fn main() raises:
    send_and_receive("Hello world!")

What version are you using? I’m in process of supporting Mojo 25.4 but the current buffer size is 64K not 1K, so it’s weird

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.