Skip to content

Commit

Permalink
feat: log info to console when polyfill-ed; add test/* pages (#3)
Browse files Browse the repository at this point in the history
also, created a raw websocket endpoint on deno:

<img width="1218" alt="image"
src="https://user-images.githubusercontent.com/65603/225317842-92d4cabd-fd33-48ca-abb7-963167323d04.png">
  • Loading branch information
fanweixiao committed Mar 15, 2023
1 parent 7cf7e7f commit b5407f4
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 95 deletions.
30 changes: 21 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@ It supports sending data both unreliably via its datagram APIs, and reliably via

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](https://webtransport.day).
>
*Link:* https://web.dev/webtransport#try-it-out

However, WebTransport is not widely supported by browsers yet:
However, WebTransport is not widely supported by browsers yet:

<img width="1367" alt="image" src="https://user-images.githubusercontent.com/65603/220812476-a384468a-39ab-4d7f-b9ad-645ec4e3c6fe.png">

Expand All @@ -38,6 +38,12 @@ You can install the WebTransport polyfill using npm:
npm install @yomo/webtransport-polyfill
```

for browser:

```html
<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:
Expand All @@ -52,21 +58,27 @@ Create a connection:
const conn = new WebTransportPolyfill('https://api.example.com');
```

Then, use the WebTransport API to send and receive data:
send data:

```javascript
// Sending data
const encoder = new TextEncoder();
const message = encoder.encode('Hello, world!');
conn.send(message);
```

receive data:

```javascript
// Receiving data
const decoder = new TextDecoder();
const data = await conn.receive();
const message = decoder.decode(data);
console.log(message);
```

more examples can be found here: [test/write.html](./test/write.html)

### 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](https://www.w3.org/TR/webtransport/)
Expand All @@ -81,27 +93,27 @@ WebTransport and WebSocket are both technologies that enable real-time communica

### Protocol

WebSocket uses a single underlying protocol (WebSocket protocol) for both transport and application layer,
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.
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.
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.
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.
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
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@yomo/webtransport-polyfill",
"version": "1.0.4-alpha2",
"version": "1.0.4-alpha3",
"description": "WebTransport implementation to fallback to WebSocket if browser does not support it",
"keywords": [
"webtransport",
Expand Down
7 changes: 3 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ export class WebTransportPolyfill {
this.#ws = new WebSocket(url);
this.#ws.binaryType = 'arraybuffer';

console.log('using webtransport polyfill!');
console.info("%cWebTransport polyfilled", "color: white; background-color: green");

this.closed = new Promise((resolve, reject) => {
if(!this.#ws) {
if (!this.#ws) {
return reject(Error('WebTransport is closed'));
}
this.#ws.addEventListener('close', (error) => {
Expand All @@ -33,7 +33,7 @@ export class WebTransportPolyfill {
});

this.ready = new Promise((resolve, reject) => {
if(!this.#ws) {
if (!this.#ws) {
return reject(Error('WebTransport is closed'));
}

Expand Down Expand Up @@ -72,7 +72,6 @@ export class WebTransportPolyfill {
if (typeof window !== 'undefined') {
if (typeof window.WebTransport === 'undefined') {
window.WebTransport = WebTransportPolyfill;
console.info("%cWebTransport polyfilled", "color: white; background-color: green");
}
}

Expand Down
79 changes: 46 additions & 33 deletions test/closed.html
Original file line number Diff line number Diff line change
@@ -1,38 +1,51 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="../dist/index.global.js"></script>
</head>
<body>
<div>
Open in firefox
</div>
<script>
(async () => {
var uid = "ws-" + (Math.random() + 1).toString(36).substring(7);
const url = `https://lo.yomo.dev:8443/v1?publickey=kmJAUnCtkWbkNnhXYtZAGEJzGDGpFo1e1vkp6cm&id=${uid}`;
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
);
});
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="../dist/index.global.js"></script>
</head>

<body>
<div>
Please open this file in firefox or Safari after `pnpm run build`
</div>
<script>
let transport
(async () => {
var uid = "ws-" + (Math.random() + 1).toString(36).substring(7);
const url = `https://wsss.deno.dev/?id=${uid}`;
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 fulfills, the connection can be used.
await transport.ready;

console.log("connected")
})();

// setTimeout(() => {
// transport.close({
// closeCode: 017,
// reason: 'CloseButtonPressed'
// })
// }, 3000)
</script>
</body>

// Once .ready fulfills, the connection can be used.
await transport.ready;
})();
</script>
</body>
</html>
99 changes: 51 additions & 48 deletions test/write.html
Original file line number Diff line number Diff line change
@@ -1,56 +1,59 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="../dist/index.global.js"></script>
</head>
<body>
<div>
Open in firefox
</div>
<script>
(async () => {
var uid = "ws-" + (Math.random() + 1).toString(36).substring(7);
const url = `https://lo.yomo.dev:8443/v1?publickey=kmJAUnCtkWbkNnhXYtZAGEJzGDGpFo1e1vkp6cm&id=${uid}`;
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
);
});
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="../dist/index.global.js"></script>
</head>

// Once .ready fulfills, the connection can be used.
await transport.ready;
<body>
<div>
Open in firefox
</div>
<script>
(async () => {
var uid = "ws-" + (Math.random() + 1).toString(36).substring(7);
const url = `https://wsss.deno.dev/?id=${uid}`;
const transport = new WebTransport(url);

// Send two datagrams to the server.
const writer = transport.datagrams.writable.getWriter();
const data1 = new Uint8Array([65, 66, 67]);
const data2 = new Uint8Array([68, 69, 70]);
writer.write(data1);
writer.write(data2);
// 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
);
});

// Read datagrams from the server.
const reader = transport.datagrams.readable.getReader();
while (true) {
const { value, done } = await reader.read();
if (done) {
break;
}
// value is a Uint8Array.
console.log(value);
// Once .ready fulfills, the connection can be used.
await transport.ready;

// Send two 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)

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

</html>

0 comments on commit b5407f4

Please sign in to comment.