I am trying to figure out how to be able to listen for incoming messages over a WebSocket connection without blocking the game execution.
In my attempt to implement this I have used the lua-websocket_example the by @britzl, which in turn is based on lua-websockets. After some reading, my approach was to use a timeout and a coroutine, and in short my code looks like this:
-- game.script:
local websocket = require("websocket")
function init(self)
self.ws = websocket.client.new({timeout=1})
local ok, err = self.ws:connect("ws://gameserver:8080", "")
self.co = coroutine.create(websocket_read)
end
function update(self, dt)
local status, server_message = coroutine.resume(self.co, self)
if status and server_message ~= nil then
msg.post("#gui", "server_message", server_message)
end
end
function websocket_read(self)
while true do
local message, opcode, was_clean, code, reason = self.ws:receive()
if message ~= nil then
coroutine.yield(message)
else
print("WS rcve:", message, opcode, was_clean, code, reason) -- debug print
coroutine.yield()
end
end
end
The problem here is that after the first read times out, any following atempt to receive a message gives the error “1006 wrong state”. If the timeout is reduced to zero it fails with timeout already when trying to connect; and if no timeout is used, the read is blocking the rest of the program while waiting for a new message.
Is there anyone here who has successfully implemented a non-blocket WebSocket message listener?
Any help to figure out how to solve this is much appreciated!