Skip to content
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

Experimental HTTP3 #742

Closed
ghost opened this issue May 13, 2022 · 19 comments
Closed

Experimental HTTP3 #742

ghost opened this issue May 13, 2022 · 19 comments

Comments

@ghost
Copy link

ghost commented May 13, 2022

There is now a HIGHLY experimental HTTP3 server built-in on x64 Linux binaries in unreleased binaries branch (npm install uNetworking/uWebSockets.js#binaries)

  • uWS.startQuicServer() launches a hello world server on port 9004 ipv6 ::1
  • It will not work if your localhost interface has no ipv6 address.
  • You can reach it by ./quiche-client --no-verify https://[::1]:9004/
  • I just remembered certs must lie in /home/alexhultman/uWebSockets.js/misc folder, so until I fix this nobody but me can run it 😉 But this will be fixed soon.
  • This function is obviously just a smoke test and will be replaced with proper uWS.QuicApp interfaces!
@uasan
Copy link

uasan commented May 13, 2022

You may be interested to have autotests and relative results of other servers, here is a ready-made solution
https://interop.seemann.io/

P.S.
By last spec recommend not to use the word QUIC in high level interfaces, recommend instead H3 and WebTransport )

@ghost
Copy link
Author

ghost commented May 15, 2022

uWS::H3App is good

@ghost
Copy link
Author

ghost commented May 15, 2022

https://github.com/uNetworking/uWebSockets.js/blob/master/examples/H3lloWorld.js

This example works and is programmable. I just need to fix the hardcoded cert paths, port and localhost address then it should be testable by others.

@uasan
Copy link

uasan commented May 15, 2022

Doing so, means you’ll be able to swap from uWS.App to uWS.H3App without changing any of your business logic — uWebSockets.js exposes HTTP/3 under the same very interface as it does HTTP/1.1.

Sounds cool for businessmen, but I'm an engineer and I doubt that compatibility will be 100%, but the goals are correct )

@ghost
Copy link
Author

ghost commented May 16, 2022

Server pushes are only allowed to happen if the client side has agreed to them. In HTTP/3 the client even sets a limit for how many pushes it accepts by informing the server what the max push stream ID is. Going over that limit will cause a connection error.

Since you still need to handle a failed push, and the fact pushes are merely optimization attempts, you can have the same interface for http 1, only that those pushes always fails

@ghost
Copy link
Author

ghost commented May 16, 2022

This is the same idea about making quic and TCP the same interface in uSockets; you just need to introduce the concept of streams inside connections, only that a TCP connection has a maximum of 1 stream.

Over generalization like this will allow everything to be more or less identical across all transports

@uasan
Copy link

uasan commented May 16, 2022

uWS is primarily interested in a high-performance implementation of websocket, H3 is interesting in a possible implementation of WebTransport, my doubts were about the possibility of making a backward compatible websocket interface with WebTransport.

@ghost
Copy link
Author

ghost commented May 17, 2022

I don't agree. I think the killer demo/feature would be to make a standalone proxy that does WebSocket to WebTransport termination. A single binary you install with curl and run boom now you can test WebTransport. And when people feel like they want to invest more they use the server library directly

@ghost
Copy link
Author

ghost commented May 17, 2022

People want simplicity and familiarity, and they want to hit the ground running.

@hpx7
Copy link

hpx7 commented Jun 12, 2022

@alexhultman does the experimental http3 work include support for WebTransport that we can test, or is that yet to be implemented?

@ghost
Copy link
Author

ghost commented Jun 12, 2022

No but it will be very interesting to benchmark it when it becomes a standard.

@hpx7
Copy link

hpx7 commented Jun 12, 2022

Do you know where to track progress of WebTransport becoming a standard? I saw that HTTP/3 just became a standard but not sure about WebTransport

@ghost
Copy link
Author

ghost commented Jun 12, 2022

No I'm also wondering. WebTransport is a tiny layer above Http3 so maybe it will land soon?

@e3dio
Copy link
Contributor

e3dio commented Jun 12, 2022

WebTransport client has been available in Chrome Stable since v97 Jan 4 2022, you can open a console and use it right now. It needs a easy to use server preferably JavaScript, that would have large demand for those who need it. Not everyone needs it and WebSocket is a good easy option, if you have lots of streams and need low latency WebTransport is good

const wt = new WebTransport(url);

@ghost
Copy link
Author

ghost commented Jun 12, 2022

Yep but it's still a draft. And I'm still wondering how popular services like Cloudflare will support it. Until all that is figured out there's no reason to rush

@ghost
Copy link
Author

ghost commented Jun 12, 2022

I expect Cloudflare to expose WebTransport as a proxy to WebSocket origin servers.

@e3dio
Copy link
Contributor

e3dio commented Jun 14, 2022

Below is quick reference to the WebTransport browser client API:

const wt = new WebTransport(url);

// Datagram read
for await (const data of wt.datagrams.readable) { /* datagram message */ }

// Datagram write
const writer = wt.datagrams.writable.getWriter();
writer.write(data);

// Incoming Uni-Directional Streams
for await (const stream of wt.incomingUnidirectionalStreams) {
   for await (const chunk of stream) { /* stream chunk */ }
}

// Create Uni-Directional Streams
const stream = await wt.createUnidirectionalStream();
const writer = stream.getWriter();
writer.write(data);

// Incoming Bi-Directional Streams
for await (const duplexStream of wt.incomingBidirectionalStreams) {
   // read
   for await (const chunk of duplexStream.readable) { /* stream chunk */ }
   // write
   const writer = duplexStream.writable.getWriter(); writer.write(data);
}

// Create Bi-Directional Streams
const duplexStream = await wt.createBidirectionalStream();
// read
for await (const chunk of duplexStream.readable) { /* stream chunk */ }
// write
const writer = duplexStream.writable.getWriter(); writer.write(data);

The server API could look like anything, here is potential mockup:

// App options, Incoming Streams and Datagram messages 
app.wt('/', {
   open: (wt) => {}, // new WebTransport connection
   datagram: (wt, arrayBuffer) => {}, // incoming datagram message
   stream: (wt, stream) => {}, // new incoming Bi or Uni directional stream
   close: (wt, code) => {}, // wt closed
});

// Stream methods
stream.write(data);
stream.subscribe(topic);
stream.onData(arrayBuffer => {});
stream.onClose(code => {});
stream.close(code);

// WT methods
wt.datagram(data);
wt.subscribeDatagram(topic);
stream = wt.stream(options);
wt.close(code);

// App methods
app.publishDatagram(topic, data);
app.publishStream(topic, data);

@ghost
Copy link
Author

ghost commented Jun 14, 2022

I've taken a look at WebTransport in lsquic and looked at the draft. This will need support in lsquic, it's not possible to implement WT without inherent support in lsquic.

@uasan
Copy link

uasan commented Jul 7, 2022

Link to track the status of the development of WebTransport in Safari
WebKit/standards-positions#18

@uNetworking uNetworking deleted a comment Aug 31, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants