You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@ayZagen you are welcome to experiment with it. ws is built on top of the upgrade mechanism for HTTP/1.1 and works with a raw (net.Socket) TCP socket.
The way WebSocket works over HTTP/2 is different, the HTTP/2 API is different so it's not trivial to add support for it. Here is a proof of concept: https://github.com/jasnell/http2ws/blob/master/http2ws.js. It might be easier to write a wrapper module with the eventual required additions in ws instead of adding support directly in ws.
I am personally not interested in having HTTP/2 support because I think there is no real benefit in using an HTTP/2 stream instead of a raw TCP socket as the transport layer. I understand that in some cases it might be desirable to support HTTP/2 and WebSocket on the same server but I think that in many cases having a separate HTTP/1.1 server only for WebSocket is a good and viable option.
Reacted by ayZagen, Adrian Pascu, Jon Dubois, Matei Radu, Anatoly Y., Yahor Siarheyenka, jonyrock-back, Tsvetan Ganev, evegreen, Bradley Odell and 8 more
Reacted by Ali Rahbari, Steven Farley, DevMiner, Jems, Nishant Dani, elyx0, Baptiste REBILLARD, Carson McManus, Adarsh Madrecha, WilberthGamboaDonde and 3 more
I'm using node's http2 framework with the allowHTTP1: true option. Then setting a ws server to listen on the http2 server just works.
Although I would like to see ws support for HTTP2 so it feels less hacky.
Reacted by Roger Padilla, Helex, mister.z, Yahor Siarheyenka, Sceat, Michael Stramel, Christopher Yovanovitch, tarkh, Robert Grant, Baptiste REBILLARD and 5 more
Reacted by Roger Padilla, Helex, Yahor Siarheyenka, Michael Stramel, Christopher Yovanovitch and Vinson Chuong
Reacted by Roger Padilla, Helex, Yahor Siarheyenka, Michael Stramel and Christopher Yovanovitch
@lpinca the big advantage (architecturally) is taking advantage of multiplexing. Right now using websockets sort of requires you to throw away any http-like abstractions (and indeed we often just open a single ws connection to ws://example.com/ws or something) and do our own multiplexing.
With ws over h2 it can start making sense again for applications / APIs to add per-URL websocket connections for specific change feeds / use cases. (Since all connections are multiplexed through the single h2 tcp socket anyway).
The other advantage is faster connection times, since if the page is loaded over h2 then we don't need to do another tcp/TLS handshake to open a websocket.
WebSocket over HTTP2 has only one advantage that is as you said the use of a single TCP connection when the origin is the same. In all other cases there are only disadvantages especially on the server and with the Node.js HTTP2 implementation.
Node.js HTTP2 adds a lot of overhead over a plain {net,tls}.Socket. There are streams wrapping other streams and the whole HTTP2 machinery. I did not run any benchmark but I'm pretty sure it would perform way worse in terms of both speed and especially memory usage.
@adelyte-chrisRFC 8441 describes how to run the WebSocket protocol over a single stream of an HTTP/2 connection and this is already supported by Node.js.
That said, I did not change my mind on this topic.
Reacted by Jesús Leganés-Combarro, MrSorcus and Nik
@szmarczak it looks like you've managed to implement websockets over HTTP2 on both client side and server side using node's http2 module and this ws library. Is that production ready or are there other things that is still needed for full websocket over http2 support? (Like ping/pong... etc).
Use of ws server-side seems to work fine as-is with a native chromium WebSocket API client. HTTP/1 requests hit the "upgrade" event and HTTP/2 requests hit the "connect" event.
Only thing I could imagine adding to ws might be a convenience handleConnect method to the server class, but that saves what - like 15 LOC?
Node.js native http2 from "node:http2" for v20.10.0:
@ackava, i believe most browsers should respect the server's ALPN negotiation, but yeah if your server reports http2 and support for extended connect (re: RFC 8441) i would expect chrome to try websocket over http2.
i haven't seen that disconnect issue on chrome 121.0.6167.185 or edge 123.0.2406.0. are you getting anything in the browser console, or perhaps have a proxy between the browser and the server?
@brentmjohnson Please Disregard my comment, the issue is with engine.io not handling connect event, your workaround does work correctly. I am currently using your work around to connect to socket.io over http1 and proxy the messages (yes overkilling CPU).
See nodejs/node#23284 (comment). To answer your question, when someone interested in having the feature, will implement it and open a PR.
I am thinking about forking ws, changing it all to TypeScript, ESM, adding a handleConnect method for http/2 and dropping utf-8-validate module support for old versions of Node.js.
If I do, do you want me to submit a pull request for the total rewrite and let you publish a new major release 9.x.x, or would you prefer me to just make a separate npm package with a different name?
Activity
lpinca commentedon Oct 15, 2018
See nodejs/node#23284 (comment). To answer your question, when someone interested in having the feature, will implement it and open a PR.
ayZagen commentedon Dec 25, 2018
@lpinca We rely on ws and want to upgrade our servers to http2. It would be great to have http2 support on ws.
Thanks
lpinca commentedon Dec 25, 2018
@ayZagen you are welcome to experiment with it. ws is built on top of the upgrade mechanism for HTTP/1.1 and works with a raw (net.Socket) TCP socket.
The way WebSocket works over HTTP/2 is different, the HTTP/2 API is different so it's not trivial to add support for it. Here is a proof of concept: https://github.com/jasnell/http2ws/blob/master/http2ws.js. It might be easier to write a wrapper module with the eventual required additions in ws instead of adding support directly in ws.
I am personally not interested in having HTTP/2 support because I think there is no real benefit in using an HTTP/2 stream instead of a raw TCP socket as the transport layer. I understand that in some cases it might be desirable to support HTTP/2 and WebSocket on the same server but I think that in many cases having a separate HTTP/1.1 server only for WebSocket is a good and viable option.
FallingSnow commentedon Jan 17, 2019
I'm using node's http2 framework with the
allowHTTP1: trueoption. Then setting awsserver to listen on the http2 server just works.Although I would like to see
wssupport for HTTP2 so it feels less hacky.josephg commentedon Jul 18, 2019
@FallingSnow does that do websockets over http2 or is that just falling back to websockets over http1.1?
josephg commentedon Jul 18, 2019
@lpinca the big advantage (architecturally) is taking advantage of multiplexing. Right now using websockets sort of requires you to throw away any http-like abstractions (and indeed we often just open a single ws connection to
ws://example.com/wsor something) and do our own multiplexing.With ws over h2 it can start making sense again for applications / APIs to add per-URL websocket connections for specific change feeds / use cases. (Since all connections are multiplexed through the single h2 tcp socket anyway).
The other advantage is faster connection times, since if the page is loaded over h2 then we don't need to do another tcp/TLS handshake to open a websocket.
lpinca commentedon Jul 18, 2019
WebSocket over HTTP2 has only one advantage that is as you said the use of a single TCP connection when the origin is the same. In all other cases there are only disadvantages especially on the server and with the Node.js HTTP2 implementation.
Node.js HTTP2 adds a lot of overhead over a plain
{net,tls}.Socket. There are streams wrapping other streams and the whole HTTP2 machinery. I did not run any benchmark but I'm pretty sure it would perform way worse in terms of both speed and especially memory usage.See also this discussion dotnet/aspnetcore#7801 and in particular this comment dotnet/aspnetcore#7801 (comment).
FallingSnow commentedon Jul 20, 2019
@josephg I believe the connection comes in as an HTTP1.1 request. There is no actual HTTP2 as far as I'm aware.
damianobarbati commentedon Aug 14, 2019
Check this out guys: https://nodejs.org/api/http2.html section "The Extended CONNECT Protocol"
LongTengDao commentedon Apr 8, 2020
By read all source code of
ws(as server side), and find each place usingsocket, it seems that we only need do small change to support HTTP2:socket.write('HTTP/1.1 101 Switching Protocols\r\n...')change tosocketOrStream.additionalHeaders ? socketOrStream.additionalHeaders({ ':status': 101, ... }) : socketOrStream.write('...');socket.setNoDelay();change tosocketOrStream.setNoDelay && socketOrStream.setNoDelay();;dataenderrorclosechange to socketOrStream.ondataenderrorcloseframeErroraborted, and remember remove them at right time.Because
net.Socketand(Server)Http2Streamare bothstream.Duplex.masx200 commentedon Apr 24, 2020
Do any browsers support "websocket over http2" now?
adelyte-chris commentedon May 12, 2020
HTTP/2 explicitly disallows WebSocket upgrades. See HTTP/2 Issue #386 for the current status of adding WebSockets semantics to HTTP/2.
lpinca commentedon May 13, 2020
@adelyte-chris RFC 8441 describes how to run the WebSocket protocol over a single stream of an HTTP/2 connection and this is already supported by Node.js.
That said, I did not change my mind on this topic.
adelyte-chris commentedon May 15, 2020
@lpinca My mistake, I saw the draft status of the RFC linked in the issue and didn't follow up to see if it had progressed.
@masx200 Chromium has support for WebSockets over HTTP/2 behind a command line flag. I found a reference to Firefox support being in development but can't find a tracking issue for it.
note8g2018 commentedon Aug 14, 2020
No
2 remaining items
luncheon commentedon Apr 12, 2021
FYI: Websockets over HTTP/2 will be supported (enabled by default) in Chrome 91
https://www.chromestatus.com/feature/6251293127475200
szmarczak commentedon Apr 12, 2021
Here's a client example using
http2-wrapper: https://github.com/szmarczak/http2-wrapper/blob/master/examples/ws/index.jspiranna commentedon Jan 11, 2023
Chrome 95 already supports that: https://chromestatus.com/feature/6251293127475200
esinanturan commentedon May 27, 2023
Any plans for supporting it in this library ?
CMCDragonkai commentedon Aug 2, 2023
@szmarczak it looks like you've managed to implement websockets over HTTP2 on both client side and server side using node's http2 module and this ws library. Is that production ready or are there other things that is still needed for full websocket over http2 support? (Like ping/pong... etc).
Also why did you do this:
What is the
100 * 1024 * 1024?brentmjohnson commentedon Dec 14, 2023
Use of ws server-side seems to work fine as-is with a native chromium WebSocket API client. HTTP/1 requests hit the "upgrade" event and HTTP/2 requests hit the "connect" event.
Only thing I could imagine adding to ws might be a convenience handleConnect method to the server class, but that saves what - like 15 LOC?
Node.js native http2 from "node:http2" for v20.10.0:
Thanks for a great library!
lpinca commentedon Dec 15, 2023
@brentmjohnson your example only covers the server side and skipping
wsServer.handleUpgrade()in the http2 case means ignoringverifyClient,'headers'event, etc.).permessage-deflatenegotiation.ackava commentedon Feb 14, 2024
Chrome 121 onwards sends websocket over http/2, so WebSocket over HTTP2 is now kind of mandatory.
@brentmjohnson your method works, however the socket is closed by Chrome browser after few seconds and it reconnects the server back again.
brentmjohnson commentedon Feb 15, 2024
@ackava, i believe most browsers should respect the server's ALPN negotiation, but yeah if your server reports http2 and support for extended connect (re: RFC 8441) i would expect chrome to try websocket over http2.
i haven't seen that disconnect issue on chrome 121.0.6167.185 or edge 123.0.2406.0. are you getting anything in the browser console, or perhaps have a proxy between the browser and the server?
ackava commentedon Feb 28, 2024
@brentmjohnson Please Disregard my comment, the issue is with engine.io not handling connect event, your workaround does work correctly. I am currently using your work around to connect to socket.io over http1 and proxy the messages (yes overkilling CPU).
masx200 commentedon Mar 29, 2024
any update?
william-kerr commentedon Apr 8, 2025
I am thinking about forking
ws, changing it all to TypeScript, ESM, adding a handleConnect method for http/2 and dropping utf-8-validate module support for old versions of Node.js.If I do, do you want me to submit a pull request for the total rewrite and let you publish a new major release 9.x.x, or would you prefer me to just make a separate npm package with a different name?
luislobo commentedon Apr 8, 2025
Probably not of any value but you got my +1 @william-kerr
lpinca commentedon Apr 9, 2025
@william-kerr if you do that, use a separate package with a different name.
william-kerr commentedon Apr 9, 2025
@lpinca, thanks for the quick reply, just wanted to reach out first for goodwill before doing something like that.