Skip to content

WebTransport implementation to fallback to WebSocket if browser does not support it

License

Notifications You must be signed in to change notification settings

yomorun/webtransport-polyfill

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

20 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

webtransport-polyfill NPM MIT Discord

The WebTransport Polyfill is a library that allows you to use the WebTransport API in browsers that do not support it natively by fallback to WebSocket.

🍱 WebTransport

WebTransport is a web API that uses the HTTP/3 protocol as a bi-directional transport. It's intended for two-way communication between a web client and an HTTP/3 server. It supports sending data both unreliably via its datagram APIs, and reliably via its streams APIs.

WebTransport enables low-latency, high-throughput communication between clients and servers, which is useful for applications such as SaaS with real-time collaboration feature, gaming, live streaming, video conferencing, and more.

Try it out The best way to experiment with WebTransport is to start up a compatible HTTP/3 server. You can then use this page with a basic JavaScript client to try out client/server communications.

Additionally, a community-maintained echo server is available at webtransport.day.

Link: https://web.dev/webtransport#try-it-out

However, WebTransport is not widely supported by browsers yet:

image

Link: https://caniuse.com/?search=webtransport

Frontend developers have to spend time and effort between high performance networking and browser compatibility. This polyfill project allows developers to use the WebTransport API in browsers that do not support it natively by providing a fallback transport mechanism and implementing the WebTransport protocol on top of it.

🍜 Getting Started

Installation

You can install the WebTransport polyfill using npm:

npm install @yomo/webtransport-polyfill

for browser:

<script src="https://unpkg.com/@yomo/webtransport-polyfill@latest/dist/index.global.js" async></script>

Usage

To use the WebTransport polyfill, you need to import it into your JavaScript code:

import { WebTransportPolyfill } from "@yomo/webtransport-polyfill";

Create a connection:

const url = `https://wsss.deno.dev/`;
const transport = new WebTransport(url);

// Optionally, set up functions to respond to the connection closing:
transport.closed
  .then(() => {
    console.log(`The HTTP/3 connection to ${url} closed gracefully.`);
  })
  .catch((error) => {
    console.error(`The HTTP/3 connection to ${url} closed due to `, error);
  });

// Once .ready fulfilled, the connection can be used
await transport.ready;

// Sending datagrams to the server
const writer = transport.datagrams.writable.getWriter();
const data1 = new Uint8Array([65, 66, 67]);
const data2 = new Uint8Array([68, 69, 70, 71]);
writer.write(data1);
setTimeout(() => {
  writer.write(data2);
}, 1e3);

setTimeout(() => {
  // close the connection
  transport.close({
    closeCode: 3000,
    reason: "close connection by setTimeout",
  });
}, 3e3);

// Read datagrams from the server.
const reader = transport.datagrams.readable.getReader();
while (true) {
  const { value, done } = await reader.read();
  if (done) {
    break;
  }
  console.log(value);
}

more examples can be found here: test/write.html

Test

pnpm run test

Limitations

The WebTransport polyfill is not a full implementation of the WebTransport API, and APIs may change as this project is following W3C Working Draft

The polyfill consists of two parts: a client-side JavaScript library that exposes the WebTransport API to your web app, and a server-side backend that handles WebSocket and WebTransport connections simultaneously, the source code can be found here: https://github.com/yomorun/presencejs.

To use this polyfill, you need to install and run the server component on your own machine or cloud service. You will also need to include the client-side library in your web app and create a WebTransport object with your server's URL. The polyfill will automatically detect wether the browser supports WebTransport natively or not, and use the appropriate transport layer accordingly. You can then use the WebTransport object as you would normally do with the native API.

πŸ₯‘ WebTransport vs WebSocket: Comparison

WebTransport and WebSocket are both technologies that enable real-time communication between clients and servers over the web. However, there are some key differences between them.

Protocol

WebSocket uses a single underlying protocol (WebSocket protocol) for both transport and application layer, while WebTransport uses a separate transport protocol (QUIC) and application protocols (e.g., HTTP, WebSocket, and HTTP/3).

Multiplexing

WebTransport allows for multiplexing of multiple streams over a single connection, which enables better resource utilization and lower latency. WebSocket does not support multiplexing by default, but it can be achieved using various techniques such as sub-protocols.

Security

WebTransport provides built-in security features such as encrypted transport and origin authentication. WebSocket does not provide built-in security features, but it can be secured using SSL/TLS.

Flexibility

WebTransport is designed to be more flexible than WebSocket, as it can support different application protocols, including WebSocket, HTTP/3, and others. WebSocket is limited to the WebSocket protocol only.

Performance

WebTransport is designed to be faster and more efficient than WebSocket, especially in high-latency and low-bandwidth environments. This is due to the use of the QUIC transport protocol, which is optimized for performance in these types of environments.

Conclusion

WebTransport and WebSocket are two web APIs that offer different trade-offs between performance, flexibility, reliability, and compatibility. WebTransport may be a better choice for applications that require low-latency, event-driven communication . While WebSocket is a well-established technology that has been widely adopted for real-time communication over the web, WebTransport is a newer technology that offers several advantages in terms of flexibility, security, and performance through multiple streams per connection and unreliable datagrams. However, WebTransport is not yet widely supported by browsers and servers, hopefully this project helped.

🍻 Contributing

If you would like to contribute to the WebTransport polyfill, please fork the repository and submit a pull request. You can also submit issues or feature requests on the GitHub page.

Build:

bun run build

Test:

bun run test

e2e:

bunx serve out

Verify Publish:

npm pack dry-run

Publish:

npm publish

Public WebSocket Test Server

We deploy a public WebSocket server on Deno for testing the WebTransport polyfill: https://wsss.deno.dev.

source code:

import { serve } from "https://deno.land/std@0.180.0/http/server.ts";

var a = 0;

serve((_req) => {
  console.log("> got a _req!");
  const upgrade = _req.headers.get("upgrade") || "";
  if (upgrade.toLowerCase() != "websocket") {
    return new Response("request isn't trying to upgrade to websocket.");
  }
  const { socket, response } = Deno.upgradeWebSocket(_req);
  socket.onopen = () => console.log("socket opened", (new Date()).valueOf());
  socket.onmessage = (e) => {
    console.log(">[" + ++a + "] socket message:", Deno.inspect(e.data));
    socket.send(
      "received length=" + e.data.byteLength + " timestamp:" + new Date(),
    );
  };
  socket.onerror = (e) => console.log("socket errored:", e.message);
  socket.onclose = () => console.log("socket closed");
  return response;
}, { port: 6000 });

console.log("working");

Test on your local dev machine

we set domain lo.yomo.dev to 127.0.0.1 for development purpose, frontend developers can use this domain to test WebTransport polyfill on their local dev.

$ dig +all @8.8.8.8 lo.yomo.dev

; <<>> DiG 9.10.6 <<>> +all @8.8.8.8 lo.yomo.dev
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 19969
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;lo.yomo.dev.			IN	A

;; ANSWER SECTION:
lo.yomo.dev.		600	IN	A	127.0.0.1

;; Query time: 65 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Sun Mar 19 12:34:09 CST 2023
;; MSG SIZE  rcvd: 56

πŸ₯‘ License

The WebTransport Polyfill is licensed under the MIT License. See the LICENSE file for more information.