Sling Academy
Home/JavaScript/Send Unreliable or Partially Ordered Data via JavaScript WebTransport

Send Unreliable or Partially Ordered Data via JavaScript WebTransport

Last updated: December 14, 2024

WebTransport is a new experimental API that provides bidirectional, low-latency transport capabilities between a browser and a server. It's designed for web applications needing functionality similar to that of WebSockets but with more control over data reliability and ordering, akin to that provided by QUIC protocol.

In this article, we'll delve into how to send unreliable or partially ordered data using JavaScript's WebTransport. This is particularly useful in scenarios such as real-time gaming, live streaming, or any application where speed trumps the necessity for every single packet of data arriving in order or at all.

Setting Up WebTransport

First, ensure you're using an environment that supports the WebTransport API, typically a Chrome browser or another supporting platform. As it might be an experimental feature, you may need to enable it manually.

A simple server setup using Node.js and QUIC might look like this:

// Node.js QUIC library may need specific setup
const http2 = require('http2');
const fs = require('fs');

const server = http2.createSecureServer({
  key: fs.readFileSync('server-key.pem'),
  cert: fs.readFileSync('server-cert.pem')
});

server.on('session', (session) => {
  session.on('stream', (stream) => {
    // The incoming stream from the client
    stream.respond({ ':status': 200 });
    stream.write('Welcome to WebTransport over HTTP/3!
');
    stream.end();
  });
});

server.listen(8443);

Ensure you generate SSL certificates and place them appropriately for SSL security. This allows QUIC to work over HTTP/3, which is essential for WebTransport.

Client-Side WebTransport Initiation

On the browser side, we initiate a WebTransport connection by pointing to the server endpoint:

async function setupTransport() {
  const transport = new WebTransport('https://localhost:8443');

  try {
    await transport.ready;
    console.log('WebTransport connection established.');
  } catch (e) {
    console.error('Failed to establish connection: ', e);
    return;
  }

  return transport;
}

Here, the WebTransport object attempts to connect to our server, and upon success, we can begin data transmission.

Sending Unreliable Data

WebTransport allows sending data unreliably, meaning that lost data does not get retransmitted. This is controlled using the settings of DatagramSendStream:

async function sendUnreliableData(transport) {
  const datagramWriter = transport.datagrams.writable.getWriter();
  try {
    const encoder = new TextEncoder();
    const data = encoder.encode('Unreliable message');
    await datagramWriter.write(data);
    console.log('Unreliable data sent.');
  } catch (e) {
    console.error('Failed to send datagram:', e);
  } finally {
    datagramWriter.releaseLock();
  }
}

The datagram is written to the transport without guaranteed delivery, which is ideal for updates where the latest update supersedes previous attempts.

Managing Partially Ordered Data

In scenarios where partial ordering is necessary, WebTransport can manage streams, allowing some order control without the overhead of strict sequencing:

async function sendPartiallyOrderedData(transport) {
  const stream = await transport.createBidirectionalStream();
  const writer = stream.writable.getWriter();
  try {
    await writer.write('First ordered message.');
    await writer.write('Second ordered message.');
    console.log('Partially ordered messages sent.');
  } catch (e) {
    console.error('Failed to send message stream:', e);
  } finally {
    writer.releaseLock();
  }
}

This assumes that the client end prioritizes processing of each incoming message in at least the order it was sent, even if lossy, somewhere along the line.

Use Cases and Benefits

WebTransport offers deep advantages in specific domains such as multiplayer online games or video communication platforms where both latency and bandwidth efficiency are pivotal. Uncontrolled ordering avoids the bottleneck of data queuing when packets come out of sync, and losing a few can outweigh waiting extra seconds for retransmissions.

With an understanding of these mechanisms, developers can optimize transport layers for specific use cases requiring either high-speed transfers or relaxed reliability constraints.

Next Article: Enhance Real-Time Apps with JavaScript WebTransport Streams

Previous Article: Improve Responsiveness in Web Apps with the WebTransport API in JavaScript

Series: Web APIs – JavaScript Tutorials

JavaScript

You May Also Like

  • Handle Zoom and Scroll with the Visual Viewport API in JavaScript
  • Improve Security Posture Using JavaScript Trusted Types
  • Allow Seamless Device Switching Using JavaScript Remote Playback
  • Update Content Proactively with the JavaScript Push API
  • Simplify Tooltip and Dropdown Creation via JavaScript Popover API
  • Improve User Experience Through Performance Metrics in JavaScript
  • Coordinate Workers Using Channel Messaging in JavaScript
  • Exchange Data Between Iframes Using Channel Messaging in JavaScript
  • Manipulating Time Zones in JavaScript Without Libraries
  • Solving Simple Algebraic Equations Using JavaScript Math Functions
  • Emulating Traditional OOP Constructs with JavaScript Classes
  • Smoothing Out User Flows: Focus Management Techniques in JavaScript
  • Creating Dynamic Timers and Counters with JavaScript
  • Implement Old-School Data Fetching Using JavaScript XMLHttpRequest
  • Load Dynamic Content Without Reloading via XMLHttpRequest in JavaScript
  • Manage Error Handling and Timeouts Using XMLHttpRequest in JavaScript
  • Handle XML and JSON Responses via JavaScript XMLHttpRequest
  • Make AJAX Requests with XMLHttpRequest in JavaScript
  • Customize Subtitle Styling Using JavaScript WebVTT Integration