-
-
Notifications
You must be signed in to change notification settings - Fork 645
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add websocket support to redbean #967
base: master
Are you sure you want to change the base?
Conversation
@wingdeans, I like the simplicity of it; thank you for the patch! Is there a basic client implementation to check the server against? I like the idea of integrating with I'll have to think about the API; I wonder if |
For the initial commit I used my browser to test var sock = new WebSocket("ws://localhost:8080/ws")
sock.onmessage = console.log
sock.send("hello, world") I'm now using autobahn-testsuite with the following config and redbean echo server: {
"outdir": "./reports/servers",
"servers": [
{
"url": "ws://127.0.0.1:8080"
}
],
"cases": ["*"],
"exclude-cases": [],
"exclude-agent-cases": {}
} -- Updated Dec 28
ProgramMaxPayloadSize(20 * 1024 * 1024) -- 20Ki, for certain autobahn tests
function OnHttpRequest()
UpgradeWS()
coroutine.yield()
local fds = {[GetClientFd()] = unix.POLLIN}
while true do
unix.poll(fds)
local s, flags = ReadWS()
if flags & 0xF == 0x8 then
return
elseif flags & 0xF == 0x1 then
Write(s)
SetWSFlags(1)
coroutine.yield()
elseif flags & 0xF == 0x2 then
Write(s)
SetWSFlags(2)
coroutine.yield()
end
end
end
|
Copies part of YieldGenerator to StreamWS
@wingdeans, thank you for the updates! Do you have any feedback on my earlier comments? |
exciting!
this is setting a dynamic key while declaring a table? no idea lua could do that ❤️ |
SetStatus(101)
SetHeader('Upgrade', 'websocket')
-- Now in a WS
Write('packet part 1')
Write('packet part 2')
coroutine.yield() |
I like that! I agree that it should work and can't think of any reason why someone would not want that. We may need to be careful though, as another |
reject surrogate pairs (U+D800 to U+DFFF) reject greater than U+10FFFF
All essential tests are passing. Current API considerations:
local s, flags = ReadWS()
-- 0 = continuation, 1 = text, 2 = binary, 9 = ping, 10 = pong I plan on adding constants for these.
I'm planning on moving everything to a local s, kind = ws.Read()
if kind == ws.Text then
ws.Set(ws.Text)
elseif kind == ws.Bin then
ws.Set(ws.Bin)
end Feedback is appreciated. |
I like the API (including moving it into its own module). I was thinking about adding |
Feels nice enough ws.Write(nil) -- Upgrade without sending response
coroutine.yield()
local fds = {[GetClientFd()] = unix.POLLIN}
while true do
unix.poll(fds)
local s, t = ws.Read()
if t == ws.CLOSE then
return
elseif t == ws.TEXT then
ws.Write(s, ws.TEXT)
coroutine.yield()
elseif t == ws.BIN then
ws.Write(s, ws.BIN)
coroutine.yield()
end
end Just cleanup/tests/docs left |
Nice! Would it make sense to imply Also, what's this value https://github.com/jart/cosmopolitan/pull/967/files#diff-a937cc5818818785e079eab14ff76fa5db080fe9bd902d1ab21aa546aa79c7d1R5089 and why is it hardcoded? |
Right now it defaults to not changing the mode. That GUID is defined by the RFC.
|
Got it; it changes the current output and all subsequent ones. |
@wingdeans, |
faa6285
to
2c4b887
Compare
3048620
to
6245732
Compare
I would like websocket support in redbean #439.
I think it can be done most easily with the following Lua API, which builds on the coroutine support implemented for streaming:
This PR implements the handshake and framing, so that the above example functions.
TODO:
SetHeader('Upgrade': 'websocket')
Autobahn Test Results:
Please feel free to give criticism of the API or code; there are definitely improvements to be made.