guild icon
Toit
#WebSocket, "Invalid frame header"
Thread channel in help
davidg238
davidg238 12/29/2023 07:56 PM
When trying to migrate the example at https://github.com/toitlang/toit/discussions/1198 from the pkg-websocket to http.web_socket, I revised main initially to look like:
import http import http.request show RequestIncoming import http.web_socket import net /** Example that demonstrates a web-socket server. The server updates a counter for button presses. */ network := net.open addr_str := network.address.stringify server := http.Server main: print "Open a browser on: $network.address:8080" sessions := {:} server.listen network 8080:: | request/RequestIncoming response/http.ResponseWriter | print "enter handler" websocket := server.web_socket request response if websocket: print "ws is: $websocket" else: print "request $request.method $request.path $request.body.read" if request.path == "/": response.write spa else: print "request $request.method $request.path $request.body.read failed" print "exit handler"
When the page loads, I get:
WebSocket connection to 'ws://192.168.0.174:8080/' failed: Invalid frame header open-ws-connection @ (index):74
which corresponds to the line:
ws = new WebSocket('ws://192.168.0.174:8080');
in the page javascript.
Is this a bug in the new websocket code or cockpit error (as Session.upgrade is replaced)?
A toy sample, cobbled together from the existing server and websocket samples. It show a device generating a webpage and updating the page after user interactions, without a manual page refresh. Op...
erikcorry
erikcorry 01/02/2024 09:06 AM
The way it's expected to work is that the websocket connection is on a particular path.
erikcorry
erikcorry 01/02/2024 09:07 AM
For example ws://192.168.0.174.8080/ws
erikcorry
erikcorry 01/02/2024 09:07 AM
Then in the handler you recognize the path and don't try to upgrade to websocket protocol unless the path matches.
erikcorry
erikcorry 01/02/2024 09:08 AM
Currently it always tries to upgrade every request to websocket, which gives 400 No nonce errors that you can see in the browser console.
erikcorry
erikcorry 01/02/2024 09:09 AM
And currenly when it gets a websocket request on the path "/" it first converts to websocket, but then continues with the if request.path == "/" and sends it HTML on the websocket connection, which messes things up.
erikcorry
erikcorry 01/02/2024 09:17 AM
main: print "Open a browser on: $network.address:8080" sessions := {:} server.listen network 8080:: | request/RequestIncoming response/http.ResponseWriter | if request.path == "/ws": websocket := server.web_socket request response if websocket: print "ws is: $websocket" else if request.path == "/": response.write SPA else: print "request $request.method $request.path $request.body.read failed" response.headers.set "Content-Type" "text/plain" response.write_headers 404 response.write "Not found\n"
erikcorry
erikcorry 01/02/2024 09:18 AM
Then you also need to change the script to have: ws = new WebSocket('ws://$(addr_str):8080/ws'); with the /ws at the end.
erikcorry
erikcorry 01/02/2024 09:19 AM
Another change you need is --max-tasks=2 at least when creating the HTTP server.
erikcorry
erikcorry 01/02/2024 09:19 AM
server := http.Server --max-tasks=2
erikcorry
erikcorry 01/02/2024 09:20 AM
Actually it sometimes works with max-tasks=1 (the default).
erikcorry
erikcorry 01/02/2024 09:21 AM
Note the else in front of the if request.path == "/" which makes sure you don't do the whole router when it's a websocket connection.
davidg238
davidg238 01/02/2024 04:17 PM
doh. thanks.
davidg238
davidg238 01/04/2024 11:20 PM
Does anything jump out at you as you read the below?
Summary:
Chrome works after ~30 sec (see -- active -- , below "Click Me" button)
Firefox fails immediately.

Referencing examples/counter.toit in https://github.com/davidg238/webd , when I run:
jag run counter.toit
and view the page on Chrome, I get:
Starting web server at 192.168.0.137:8080 DEBUG: client connected {peer: 192.168.0.174:38064} DEBUG: incoming request {peer: 192.168.0.174:38064, path: /} DEBUG: client connected {peer: 192.168.0.174:38078} <after ~30 seconds> DEBUG: connection ended {peer: 192.168.0.174:38078, reason: DEADLINE_EXCEEDED} DEBUG: client connected {peer: 192.168.0.174:38082} DEBUG: incoming request {peer: 192.168.0.174:38082, path: /ws} websocket request invoked DEBUG: connection ended {peer: 192.168.0.174:38064, reason: DEADLINE_EXCEEDED} DEBUG: client socket detached {peer: 192.168.0.174:38082}

I get the first 3 lines on the console, and the page renders immediately.
The websocket shows "pending" in the Chrome developer tools/network tab.
Afer about 30 seconds, the websocket status changes to 101 and the button works.
There is no apparent request for the favicon.ico
Contribute to davidg238/webd development by creating an account on GitHub.
davidg238
davidg238 01/04/2024 11:21 PM
On Firefox, I get:
Starting web server at 192.168.0.137:8080 DEBUG: client connected {peer: 192.168.0.174:35648} DEBUG: incoming request {peer: 192.168.0.174:35648, path: /} DEBUG: client connected {peer: 192.168.0.174:35664} DEBUG: incoming request {peer: 192.168.0.174:35664, path: /ws} websocket request invoked DEBUG: connection ended {peer: 192.168.0.174:35664} DEBUG: connection ended {peer: 192.168.0.174:35648, reason: DEADLINE_EXCEEDED}
immediately. In the developer/network tab,
In the URL window:
status 200, method get, file / status 404, method get, file favicon.ico status 400, method get, file ws

In the request window:
GET http://192.168.0.137:8080/ [HTTP/1.1 200 ok 190ms] GET http://192.168.0.137:8080/favicon.ico [HTTP1.1 404 Not Found 0ms] GET ws://192.168.0.137:8080/ws [HTTP/1.1 400 No Connection: Upgrade 41mS]
hhv0001
hhv0001 01/05/2024 08:20 AM
That "30 seconds" jumps out. That's the copious timeout that can be reduced. You'll probably also need to up the number of tasks the server uses like Erik said, so add these to the server:
--max-tasks=6 --read_timeout=d
where d is
d := Duration --ms=1000
or something smaller than 30 seconds that works for you.
(edited)
davidg238
davidg238 01/05/2024 02:54 PM
Thanks. That made Chrome usable,
davidg238
davidg238 01/05/2024 02:55 PM
Firefox still fails, will look further
18 messages in total