On Thu, 21 Mar 2019 17:21:48 GMT, Foo Bar wrote:

I am working on a project (multiplayer browser-based game) that uses websockets. I structured the project so that there are 2 threads: one of them is the vibe.d web server, and the other is the actual server for the game itself.

Because of this structure, I am passing WebSockets from the webserver to the game server using std.concurrency.send. This seems to barely work though, and it is really unreliable (crashes after a few seconds). Sometimes it gives and error about core.exception.AssertError@../../.dub/packages/vibe-core-1.6.1/vibe-core/source/vibe/core/net.d(593): Assertion failure, but other times it just simply stops receiving messages from the websocket (I think this is because the game-server thread may be crashing, but I'm not sure).

Here is some minimal code that reproduces the issue:
source/app.d and public/index.html

I would really appreciate if anyone could help me fix this.
Thanks!

The thread model for vibe.d is strictly single-threaded/compartmented, with the exception of the primitives in vibe.core.sync. Unfortunately, the API of std.concurrency is not thread-safe w.r.t. type annotations and simply allows to pass any values between threads, no matter if they are shared or thread-local.

The solution is to keep the web socket in the original thread and instead pass the messages to and from the web socket using something like std.concurrency.

For performance reasons, you could also have a look at vibe.core.channel, which is a strongly typed alternative with more flexibility w.r.t. receivers and senders (not tied to a particular task or thread). If dynamic typing is needed, a tagged union (as implemented by the "taggedalgebraic" or "sumtype" DUB packages) provides a more efficient (no heap allocations) alternative to Variant, which is used by std.concurrency.