Posted Sat, 23 Mar 2019 12:47:42 GMT in reply to
Foo Bar
Reply
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
.