Extension-websocket prints "Waiting for socket to be available for reading"

Yes, that is the idea. If it will not receive data from the server, it will disconnect.

it simply didn’t receive the data

Well, as you saw in the extension output, the socket was connected, and the extension sent the first part of the handshake.
The problem then I guess, is that you server didn’t receive it/handle it?

Btw, how do you currently verify your server functionality?

You didn’t mention how you verify the server?
Do you have a test script or something?

Now the server returns 502 bad gateway:

users/grify/PerryRepro $ websocat -v -v ws://parry-host.grify.repl.co                                                               09:29:19
[INFO  websocat::lints] Auto-inserting the line mode
[DEBUG websocat] Done third phase of interpreting options.
[DEBUG websocat] Done fourth phase of interpreting options.
[DEBUG websocat] Preparation done. Now actually starting.
[DEBUG websocat::sessionserve] Serving Line2Message(Stdio) to Message2Line(WsClient("ws://parry-host.grify.repl.co/")) with Options { websocket_text_mode: true, websocket_protocol: None, websocket_reply_protocol: None, udp_oneshot_mode: false, udp_broadcast: false, udp_multicast_loop: false, udp_ttl: None, udp_join_multicast_addr: [], udp_join_multicast_iface_v4: [], udp_join_multicast_iface_v6: [], udp_reuseaddr: false, unidirectional: false, unidirectional_reverse: false, max_messages: None, max_messages_rev: None, exit_on_eof: false, oneshot: false, unlink_unix_socket: false, exec_args: [], ws_c_uri: "ws://0.0.0.0/", linemode_strip_newlines: false, linemode_strict: false, origin: None, custom_headers: [], custom_reply_headers: [], websocket_version: None, websocket_dont_close: false, websocket_ignore_zeromsg: false, one_message: false, no_auto_linemode: false, buffer_size: 65536, broadcast_queue_len: 16, read_debt_handling: Warn, linemode_zero_terminated: false, restrict_uri: None, serve_static_files: [], exec_set_env: false, no_exit_on_zeromsg: false, reuser_send_zero_msg_on_disconnect: false, process_zero_sighup: false, process_exit_sighup: false, socks_destination: None, auto_socks5: None, socks5_bind_script: None, tls_domain: None, tls_insecure: false, headers_to_env: [], max_parallel_conns: None, ws_ping_interval: None, ws_ping_timeout: None, request_uri: None, request_method: None, request_headers: [], autoreconnect_delay_millis: 20, ws_text_prefix: None, ws_binary_prefix: None, ws_binary_base64: false, ws_text_base64: false }
[DEBUG websocat::stdio_peer] get_stdio_peer (async)
[DEBUG websocat::stdio_peer] Setting stdin to nonblocking mode
[DEBUG websocat::stdio_peer] Installing signal handler
[DEBUG websocat::sessionserve] Underlying connection established
[INFO  websocat::ws_client_peer] get_ws_client_peer
[DEBUG websocat::stdio_peer] restore_blocking_status
[DEBUG websocat::stdio_peer] Restoring blocking status for stdin
websocat: WebSocketError: Received unexpected status code (502 Bad Gateway)
[DEBUG websocat::stdio_peer] restore_blocking_status
[DEBUG websocat::stdio_peer] Restoring blocking status for stdin
websocat: error running
1 Like

The server currently returns 502 because the server cannot handle the request because it is not expecting binaryData, but rather utf8Data, so it cannot and does not parse the request:

{ type: 'binary', binaryData: <Buffer 61 79 65> }
undefined:1
[object Object]

You didn’t mention how you verify the server?
Do you have a test script or something?

Remember I get this error using the application websocat, and if that doesn’t work, I’d say you need to look into your server code imho.

Yeah there’s a nodeJS-based client emulator that uses the same protocols.
Here’s the code used for the index.js of the client:

console.log("Importing files...")
const fs = require("fs")

const config = require("./config.js")
const util = require("./util.js")
// Startup

util.log("Starting test client...")

// Modules

util.log("Importing modules...")
const http = require("http")
const WebSocket = require("ws")
const WebSocketServer = require("websocket").server

// Connect to client

util.log("Connecting to client...")
const client = new WebSocket(config.serverip, config.serverprotocol)//clientProtocol

// client events

client.on("error", error => {
	//console.log("clienterr")
    util.log(error.message, true)
})

client.on("open", function() {
	console.log("serveropen")
    util.log("Connection established with server")
    util.log("Authenticating with server...")
    client.send("ping")
})

client.on("message", msg => {
    console.log(`client message received: ${msg}`)
})

client.on("close", (code, reason) => {
	//console.log("")
    util.log(`client connection closed - Code: ${code} Reason: ${reason}`)
})

It works fine with the client emulator.
Also, since the client emulator references local modules config and util, it won’t run elsewhere so here’s a version that you WILL be able to run:

const fs = require("fs")
const http = require("http")
const WebSocket = require("ws")
const WebSocketServer = require("websocket").server
console.log("Connecting to client...")
const client = new WebSocket("https://parry-host.grify.repl.co", "")
client.on("error", error => {
    console.log(error.message, true)
})
client.on("open", function() {
    console.log("Connection established with server")
    client.send("ping")
})
client.on("message", msg => {
    console.log(`client message received: ${msg}`)
})
client.on("close", (code, reason) => {
    console.log(`client connection closed - Code: ${code} Reason: ${reason}`)
})

(edit: condensed and removed comments, whitespace)

I have a fix coming up, where you can choose to send your message using a text frame (as oposed to binary). This worked with your server.

2 Likes

Try version 1.4.0 now:

I added support for sending text messages:

websocket.send(this.ws, "ping", {type = websocket.DATA_TYPE_TEXT})

And also for the connection, I added support for adding custom headers:

local params = {
    headers = "Sec-WebSocket-Protocol: chat\r\n"
}
self.ws = websocket.connect(url, params, function(self, conn, data)
    end)
3 Likes

This fixed my problems, thank you!
It all works now, but the fact that when the app first launches you have to endure the 3fps while it waits for the ws to connect is quite annoying. I totally understand if that isn’t fixable though, and I can build around it.

Glad to hear it.

However, I’m curious as to how the code still runs at 3 fps?
Previously, the code waited to receive bytes from the server, for 200ms, then continued until next frame, for the next try. I changed that number from 200ms to 4ms, so that means a theoretical frame rate of 250.

I just changed your loading.gui_script to this:

function init(self)
	msg.post("/loading#network", "connectWS")
    self.lasttime = socket.gettime()
end

function update(self, dt)
    local t = socket.gettime()
    local tdiff = t - self.lasttime
    self.lasttime = t
    print("time:", tdiff)
end

And when I output the delta time in your example, it is indeed showing 60fps:

INFO:DLIB: Log server started on port 53757
INFO:ENGINE: Target listening with name: iMac.lan - 192.168.10.210 - Darwin
INFO:ENGINE: Engine service started on port 8001
INFO:ENGINE: Defold Engine 1.2.174 (8f3e864)
INFO:WEBSOCKET: dmWebSocket::g_DebugWebSocket == 2
INFO:ENGINE: Loading data from: build/default
INFO:WEBSOCKET: Registered websocket extension
INFO:ENGINE: Initialised sound device 'default'
WARNING:WEBSOCKET: STATE_CONNECTING -> STATE_HANDSHAKE_WRITE
DEBUG:SCRIPT: time:	0.027682065963745
INFO:DLIB: SSDP: Started on address 169.254.189.218
INFO:DLIB: SSDP: Started on address 192.168.10.210
WARNING:WEBSOCKET: Sent buffer: 'GET /' 5 bytes
WARNING:WEBSOCKET: Sent buffer: '' 0 bytes
WARNING:WEBSOCKET: Sent buffer: ' HTTP/1.1\r\n' 11 bytes
WARNING:WEBSOCKET: Sent buffer: 'Host: ' 6 bytes
WARNING:WEBSOCKET: Sent buffer: 'parry-host.grify.repl.co' 24 bytes
WARNING:WEBSOCKET: Sent buffer: '' 0 bytes
WARNING:WEBSOCKET: Sent buffer: '\r\n' 2 bytes
WARNING:WEBSOCKET: Sent buffer: 'Upgrade: websocket\r\n' 20 bytes
WARNING:WEBSOCKET: Sent buffer: 'Connection: Upgrade\r\n' 21 bytes
WARNING:WEBSOCKET: Sent buffer: 'Sec-WebSocket-Key: ' 19 bytes
WARNING:WEBSOCKET: Sent buffer: 'VyniXyvL8DZvtKtSpPJdGg==' 24 bytes
WARNING:WEBSOCKET: Sent buffer: '\r\n' 2 bytes
WARNING:WEBSOCKET: Sent buffer: 'Sec-WebSocket-Version: 13\r\n' 27 bytes
WARNING:WEBSOCKET: Sent buffer: '\r\n' 2 bytes
WARNING:WEBSOCKET: STATE_HANDSHAKE_WRITE -> STATE_HANDSHAKE_READ
DEBUG:SCRIPT: time:	0.0072238445281982
WARNING:WEBSOCKET: Waiting for socket to be available for reading
DEBUG:SCRIPT: time:	0.0064589977264404
WARNING:WEBSOCKET: Waiting for socket to be available for reading
DEBUG:SCRIPT: time:	0.017199039459229
WARNING:WEBSOCKET: Waiting for socket to be available for reading
DEBUG:SCRIPT: time:	0.016463994979858
WARNING:WEBSOCKET: Waiting for socket to be available for reading
DEBUG:SCRIPT: time:	0.017044067382813
WARNING:WEBSOCKET: Waiting for socket to be available for reading
DEBUG:SCRIPT: time:	0.016397953033447
WARNING:WEBSOCKET: Waiting for socket to be available for reading
DEBUG:SCRIPT: time:	0.017458915710449
WARNING:WEBSOCKET: Waiting for socket to be available for reading
DEBUG:SCRIPT: time:	0.015980958938599
WARNING:WEBSOCKET: Waiting for socket to be available for reading
DEBUG:SCRIPT: time:	0.017051219940186
WARNING:WEBSOCKET: Waiting for socket to be available for reading
DEBUG:SCRIPT: time:	0.01646900177002
WARNING:WEBSOCKET: Waiting for socket to be available for reading
DEBUG:SCRIPT: time:	0.015687942504883
WARNING:WEBSOCKET: Waiting for socket to be available for reading
DEBUG:SCRIPT: time:	0.016798973083496
WARNING:WEBSOCKET: Received bytes: 'HTTP/1.1 101 Switching Protocols\r\nConnection: Upgrade\r\nSec-Websocket-Accept: 6QGUMdCV2TCI0KyDv5RffkPwQJU=\r\nUpgrade: websocket\r\nDate: Sun, 18 Oct 2020 07:21:06 GMT\r\nVia: 1.1 google\r\n\r\n\81\04test' 189 bytes
WARNING:WEBSOCKET: Secret key (base64): VyniXyvL8DZvtKtSpPJdGg==
WARNING:WEBSOCKET: Secret key + RFC_MAGIC: VyniXyvL8DZvtKtSpPJdGg==258EAFA5-E914-47DA-95CA-C5AB0DC85B11
WARNING:WEBSOCKET: Hashed key (sha1): '\e9\01\941\d0\95\d90\88\d0\ac\83\bf\94_~C\f0@\95' 20 bytes
WARNING:WEBSOCKET: Client key (base64): 6QGUMdCV2TCI0KyDv5RffkPwQJU=
WARNING:WEBSOCKET: Server key (base64): 6QGUMdCV2TCI0KyDv5RffkPwQJU=
WARNING:WEBSOCKET: STATE_HANDSHAKE_READ -> STATE_CONNECTED
DEBUG:SCRIPT: Connected: userdata: 0x7f9add573600
DEBUG:SCRIPT: time:	0.012922048568726
WARNING:WEBSOCKET: PushMessage 'test' 4 bytes
WARNING:WEBSOCKET: Sent buffer: '\82\84\ecFg\80' 6 bytes
WARNING:WEBSOCKET: Sent buffer: '\9c/\t\e7' 4 bytes
DEBUG:SCRIPT: Receiving: 'test'
DEBUG:SCRIPT: time:	0.016079902648926
DEBUG:SCRIPT: time:	0.016479969024658
DEBUG:SCRIPT: time:	0.0177321434021
...

Could you please provide me with a log from your scenario? (with the times printed out)

I totally understand if that isn’t fixable though

It is fixable, I just need to understand what’s causing is to behave that way.
And I don’t have a repro case for it, which makes it even harder.

1 Like

I’m trying to use the websoket but it’s not working.
do i have to do some requiere?
how to include the webscoket in the game?
I already configured in dependencies as a link;

this is my connection code;

Blockquote
function init(self)
self.url = “ws://localhost/”
local parameters = {
timeout = 3000,
headers = “Sec-WebSocket-Protocol: chat\r\nOrigin: mydomain.com\r\n”
}
self.connection = websocket.connect(self.url, params, websocket_callback)
end

but the websoket returns this error;
attempt to index global ‘websocket’ (a null value)

Hi @lumaia1990 !
This error message means that you’re running the code from an engine without the websocket support, which means that the Lua module is nil.

If you have added the dependency, in the editor, you also need to call Project -> Fetch Libraries from the editor. Then it will download the asset, and the next time you run it, it will build the engine with the new extension in it.

2 Likes

Does anyone know how I get a variable?
I’m sending it like this;
local nova = {“10”, “02”}
websocket.send(conn, “s1”, nova)
but I can’t get the data.
elseif data.event == websocket.EVENT_MESSAGE then
tostring(data.message)
with that I only receive text how do I get the variable that was sent?
end

Are you sure this works? You need to encode the data first into bytes that you can send. Try using json.encode(nova) to turn the table into a string, and then in your server to do the opposite and decode it into a format that your server can read.

1 Like

Thank you

Thanks again, I managed to get the instances to communicate but… when I made an apk to test the game over the network using websocket
android does not connect to the server.
Whenever a customer enters I give a console.log
to show his id.

Do I have to do something to make the websocket work on android?

Nope, it should work out of the box. Do you get any errors? Add some prints and check the log on the phone.

1 Like

I found the error was the self.url = “ws://localhost:3000”
As I’m testing, I made the apk with this wrong address.
I switched to the one on the pc and it worked. Thanks.

1 Like