![](/style/images/good.png)
![](/style/images/bad.png)
Creating A WebTransport NPM Package - ShakePort
source link: https://jyroneparker.com/2023/02/23/creating-a-webtransport-npm-package-shakeport/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
![webtransport.png](https://jyroneparker.com/wp-content/uploads/2023/02/webtransport.png)
People Are SLEEPING on WebTransport!
Of all my favorite HTML APIs the WebTransport API is definitely TOP 3. MDN explains the WebTransport API as such:
The
https://developer.mozilla.org/en-US/docs/Web/API/WebTransportWebTransport
interface of the WebTransport API provides functionality to enable a user agent to connect to an HTTP/3 server, initiate reliable and unreliable transport in either or both directions, and close the connection once it is no longer needed.
It allows a web page to connect to a bidirectional HTTP/3 server to send and receive UDP datagrams either reliably or unreliably. Seriously why is no one talking about this?! In this article/tutorial, I will go through the process of creating an NPM package called ShakePort
What Is HTTP/3
HTTP/3 is the third major version of the Hypertext Transfer Protocol used to exchange information on the World Wide Web, complementing the widely-deployed HTTP/1.1 and HTTP/2. Unlike previous versions which relied on the well-established TCP (published in 1974),[1] HTTP/3 uses QUIC, a multiplexed transport protocol built on UDP.[2] On 6 June 2022, IETF published HTTP/3 as a Proposed Standard in RFC9114.[3]
https://en.wikipedia.org/wiki/HTTP/3
HTTP/3 is 3x faster than HTTP/1.1 and has much less latency than its predecessors. Built using QUIC for data transfer using UDP instead of TCP. What this means for real-time sensitive applications is faster data faster execution.
Dissecting The WebTransport Class
Constructor
The constructor for the WebTransport takes in a url and an options parameter. The URL points to an instance of a HTTP/3 server to connect to. The options parameter is an optional variable that passes in a JSON object
url
A string representing the URL of the HTTP/3 server to connect to. The scheme needs to be HTTPS, and the port number needs to be explicitly specified.options
Optional
An object containing the following properties:serverCertificateHashes
Optional
An array of WebTransportHash
objects. If specified, it allows the website to connect to a server by authenticating the certificate against the expected certificate hash instead of using the Web public key infrastructure (PKI). This feature allows Web developers to connect to WebTransport servers that would normally find obtaining a publicly trusted certificate challenging, such as hosts that are not publicly routable, or ephemeral hosts like virtual machines.
WebTransportHash
objects contain two properties:algorithm
A string representing the algorithm to use to verify the hash. Any hash using an unknown algorithm will be ignored.value
A BufferSource
representing the hash value.
We instantiate a new instance of WebTransport with the following command
new WebTransport(url, options)
Instance Properties
The closed
read-only property of the WebTransport
interface returns a promise that resolves when the transport is closed.
The datagrams
read-only property of the WebTransport
interface returns a WebTransportDatagramDuplexStream
instance that can be used to send and receive datagrams — unreliable data transmission.
“Unreliable” means that transmission of data is not guaranteed, nor is arrival in a specific order. This is fine in some situations and provides very fast delivery. For example, you might want to transmit regular game state updates where each message supersedes the last one that arrives, and order is not important.
The incomingBidirectionalStreams
read-only property of the WebTransport
interface represents one or more bidirectional streams opened by the server. Returns a ReadableStream
of WebTransportBidirectionalStream
objects. Each one can be used to reliably read data from the server and write data back to it.
The incomingUnidirectionalStreams
read-only property of the WebTransport
interface represents one or more unidirectional streams opened by the server. Returns a ReadableStream
of WebTransportReceiveStream
objects. Each one can be used to reliably read data from the server.
The ready
read-only property of the WebTransport
interface returns a promise that resolves when the transport is ready to use.
Instance Methods
The close()
method of the WebTransport
interface closes an ongoing WebTransport session.
The createBidirectionalStream()
method of the WebTransport
interface opens a bidirectional stream; it returns a WebTransportBidirectionalStream
object containing readable
and writable
properties, which can be used to reliably read from and write to the server.
The createUnidirectionalStream()
method of the WebTransport
interface opens a unidirectional stream; it returns a WritableStream
object that can be used to reliably write data to the server.
Use Cases For WebTransport
Web Gaming
WebTransport allows not only for better performance web games in multiplayer, but it also allows for CROSS-SYSTEM PLAY! Since WebTransport is an HTTP/3 web standard you can implement it on the web, PlayStation, Xbox, and whatever else may come in the future! You may be wondering why use WebTransport instead of WebRTC. For 1 v 1 multiplayer games WebRTC will do just fine, but what if you want to build a Battle Royale style battle game that’s 50 v 50? If you are using WebRTC you will run into latency issues because WebRTC is peer-to-peer whereas WebTransport is client-server. Using UDP packets so order does not matter which is what you want for gaming.
![Free hand holding gaming console](https://i0.wp.com/jyroneparker.com/wp-content/uploads/2023/02/czNmcy1wcml2YXRlL3Jhd3BpeGVsX2ltYWdlcy93ZWJzaXRlX2NvbnRlbnQvbHIvcHg1NjAxMjEtaW1hZ2Uta3d2dmYyZnIuanBn.jpg?resize=546%2C364&ssl=1)
With WebTransport communicating with IOT devices via the web just got a whole lot easier. You can manage a fleet of hardware devices, get analytical data and issue commands in real-time. I am currently using a WebTransport server on my Raspberry Pi 4 and a Vue frontend to remotely control my Pi!
Machine Learning
Machine learning requires large datasets. By utilizing WebTransport you can send user data to your server in real-time to get better insights on your machine learning models. Take for example you are building a recommendation engine. As the user browses the site, you are sending data in real time based on what they are looking at, etc. The faster you can collect and analyze data, the more profitable your company can become.
Pub/Sub
Using the WebTransport API you can implement a pub/sub system. The simplest use case would be a notification engine (think game HUD updates in multiplayer). You can also do things like implement real-time tickers instead of relying on long-polling techniques.
Why I Created ShakePort
I created ShakePort as a basis for my real-time apps and more importantly, I’m building a game and need multiplayer networking. I decided at the beginning of the year I would post on average 1 open source package a month. So far I’m at 4! My philosophy is if you find yourself doing certain code over and over, just package that sh!t up and release it to the world. Chances are there are other developers who you are helping OR you could find devs to help make your package even better! The ShakePort suite is made up of a client (ShakePort Client) and a server (ShakePort Server) this tutorial will focus on the ShakePort Client, I will post the ShakePort Server tutorial later in the year once I finish.
The Code
This package is actually very simple, it only consists of two files:
- A WebWorker file
- The ShakePortClient class
Almost all of the heavy work is offloaded to the WebWorker to optimize speed and performance and utilizes window.postMessage()
to send data to the main application. This way the developer has custom control on how to deal with the datagrams.
Scaffolding
Create a new directory and run the npm init command to create a new NPM packagemkdir shakeport-client
cd shakeport-client && npm init
The WebWorker
Create a worker.js file in the root of the project and input the following:
let transport, stream = null
onmessage = (e) => {
try {
switch(e.data.event) {
case 'start':
transport = initTransport(e.data.url, e.data.options)
postMessage({event:'start', transport:transport})
break;
case 'setup-bidirectional':
stream = setUpBidirectional()
readData(stream.readable)
break;
case 'write-bidirectional':
writeData(stream.writable, e.data.data)
break;
case 'data':
break;
case 'stop':
closeTransport(e.transport)
break;
}
} catch {
postMessage({event: 'error'});
}
}
async function initTransport(url, options = {}) {
// Initialize transport connection
const transport = new WebTransport(url, options);
// The connection can be used once ready fulfills
await transport.ready;
return transport
}
async function readData(readable) {
const reader = readable.getReader();
while (true) {
const {value, done} = await reader.read();
if (done) {
break;
}
// value is a Uint8Array.
postMessage({event: 'data-read', data:value});
}
}
async function writeData(writable, data) {
const writer = writable.getWriter();
writer.write(data)
postMessage({event: 'data-written', data: data})
}
async function setUpBidirectional() {
const stream = await transport.createBidirectionalStream();
// stream is a WebTransportBidirectionalStream
// stream.readable is a ReadableStream
// stream.writable is a WritableStream
return stream
}
async function setUpUnidirectional() {
const stream = await transport.createUnidirectionalStream();
// stream is a WebTransportBidirectionalStream
// stream.readable is a ReadableStream
// stream.writable is a WritableStream
return stream
}
async function closeTransport(transport) {
// Respond to connection closing
try {
await transport.closed;
console.log(`The HTTP/3 connection to ${url} closed gracefully.`);
} catch(error) {
console.error(`The HTTP/3 connection to ${url} closed due to ${error}.`);
}
}
The ShakePortClient Class
Create a class file called ShakePortClient.js in the root directory and fill it in:
export default class ShakePortClient {
transport = null
constructor() {
const worker = require('./worker.js')
console.log(worker)
this.worker = new Worker(worker)
}
startClient(data = {url, options: {}}) {
this.worker.postMessage({event:'start', ...data})
this.worker.onmessage = (event) => {
switch(event.data.event) {
case 'start':
console.log('Started')
this.transport = event.data.transport
break;
case 'stop':
this.transport = null
break;
case 'error':
console.log(event.data.error)
break;
default:
window.postMessage(event.data)
break;
}
}
}
stopClient () {
this.worker.postMessage({event:'stop'})
}
setUpBidirectional () {
this.worker.postMessage({event:'setup-bidirectional'})
}
setUpUnidirectional () {
this.worker.postMessage({event:'setup-unidirectional'})
}
writeBidirectional (data) {
this.worker.postMessage({event:'write-bidirectional', data: data})
}
writeData (data) {
this.worker.postMessage({event:'write-data', data: data})
}
writeUndirectional (data) {
this.worker.postMessage({event:'write-unidirectional', data: data})
}
}
Using The Package
npm install @mastashake08/shakeport-client
Then import and use
Import In Your Project
import ShakePortClient from '@mastashake08/shakeport-client'
const spc = new ShakePortClient();
spc.startClient({
url:'<webtransport_server_url>'
})
Responding To Messages
window.addEventListener("message", (event) => {
// Do we trust the sender of this message? (might be
// different from what we originally opened, for example).
if (event.origin !== "http://example.com")
return;
// event.source is popup
// event.data is "hi there yourself! the secret response is: rheeeeet!"
}, false);
Follow Me On Social Media
Hackin’ on yo mainframe
mastashake08
Jyrone Parker is an American software engineer and entrepreneur from Louisville, KY. He is the owner and CEO of J Computer Solutions LLC, a full-scale IT agency that deals with hardware, networking, and software development. He is also a tech rapper and producer that goes by the name Mastashake.
Join The Newsletter
By joining the newsletter, you get first access to all of my blogs, events, and other brand-related content delivered directly to your inbox. It’s 100% free and you can opt out at any time!
Name(required)
Email(required)
By submitting your information, you're giving us permission to email you. You may unsubscribe at any time.
Like this:
Recommend
-
4
Spiderable middleware Google, Facebook, Twitter, Yahoo, and Bing and all other crawlers and search engines are constantly trying to view your website. If your website is built on top of the JavaScript framework...
-
10
Will WebTransport Replace WebRTC in Near Future?Introducing WebTransport, the successor for WebRTC for real-time web communication
-
3
什么是WebTransport? WebTransport 是WebRTC体系下的一套浏览器API,提供低延迟,client和server之间双向通信的能力。 核心的能力点包括: WebTransport 提供基于QUIC 和 HTTP3实现的API, 自动获得QUIC和HTTP3本身的特性,比如应用层的拥塞,避...
-
5
Best practices for creating a modern npm packageBrian ClarkSeptember 12, 2022Technology is always changing and your processes and practices need to keep up with those changes. So while npm is 12 years old, your pract...
-
0
Node Weekly Issue 454 « Prev
-
0
Experimental WebTransport over HTTP/3 support in Kestrel Chris R...
-
6
WebTransport 是一种新的 API,提供低延迟、双向、客户端-服务器消息传递。了解有关其用例的更多信息,以及如何就实施的未来提供反馈。 小心 此提案在初始试用期内会继续更改。浏览器实现与本文中的信息可能存在差异。 有...
-
3
Web Transport 简介 WebTransport 是一个新的 Web API,使用 HTTP/3 协议来支持双向传输。它用于 Web 客户端和 HTTP/3 服务器之间的双向通信。它支持通过 不可靠的 Datagrams API 发送数据,也支持可靠的 Stream API 发送数据。
-
5
WebTransport 开播的应用实践之路 作者:付宇豪 2023-06-12 17:24:40 网络 WebTransport可以发挥页面多线程的优势,使用WebRTC协议,大...
-
46
Explore the pivotal roles of WebSockets, Server-Sent Events, Long-Polling, WebRTC, and WebTransport in shaping real-time web apps. Dive into their unique advantages, limitations, and optimal use cases for informed development choices.
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK