Real-Time Communication
AngularTS provides five building blocks for real-time and compute-heavy work:
$ssefor Server-Sent Events.$websocketfor bidirectional WebSocket connections.$webTransportfor HTTP/3 WebTransport sessions with datagrams and streams.ng-workerfor JavaScript work in a Web Worker.ng-wasmfor loading WebAssembly modules.
Exact service and connection signatures live in TypeDoc:
SseServiceSseConfigSseConnectionWebSocketServiceWebSocketConfigWebSocketConnectionWebTransportServiceWebTransportConfigWebTransportConnectionWorkerConfigWorkerConnection
Server-Sent Events
$sse creates a managed EventSource connection. It handles query parameters, JSON message parsing, heartbeat detection, automatic reconnection, and clean shutdown.
class NewsFeedController {
static $inject = ["$sse", "$scope"];
items: NewsItem[] = [];
private connection: ng.SseConnection;
constructor($sse: ng.SseService, $scope: ng.Scope) {
this.connection = $sse("/api/news/stream", {
withCredentials: true,
params: { category: "top" },
retryDelay: 3000,
heartbeatTimeout: 30000,
onMessage: (item: NewsItem) => {
const view = $scope["$ctrl"] as NewsFeedController;
view.items = [item, ...view.items].slice(0, 50);
},
onReconnect: (attempt) => {
console.log("SSE reconnect", attempt);
},
});
$scope.$on("$destroy", () => this.connection.close());
}
}
EventSource does not support arbitrary custom headers in browsers. For authenticated streams, use cookies with withCredentials or include a short-lived token in query params.
WebSockets
$websocket returns a managed WebSocket connection with reconnects, heartbeat handling, message transforms, and send support.
class ChatController {
static $inject = ["$websocket", "$scope"];
messages: ChatMessage[] = [];
private socket: ng.WebSocketConnection;
constructor($websocket: ng.WebSocketService, $scope: ng.Scope) {
this.socket = $websocket("wss://api.example.com/chat", ["v1"], {
retryDelay: 2000,
maxRetries: 20,
onMessage: (message: ChatMessage) => {
const view = $scope["$ctrl"] as ChatController;
view.messages = [...view.messages, message];
},
onClose: (event) => {
console.log("WebSocket closed", event.code);
},
});
$scope.$on("$destroy", () => this.socket.close());
}
send(text: string) {
this.socket.send({ type: "message", text });
}
}
send() serializes values as JSON before passing them to the native WebSocket.
WebTransport
$webTransport opens a browser-native WebTransport session. Use it when an
endpoint can serve HTTP/3 and the client benefits from unreliable datagrams,
reliable streams, or both in the same session.
class TelemetryController {
static $inject = ["$webTransport", "$scope"];
events: string[] = [];
private session: ng.WebTransportConnection;
constructor($webTransport: ng.WebTransportService, $scope: ng.Scope) {
this.session = $webTransport("https://localhost:4433/webtransport", {
reconnect: true,
retryDelay: 500,
maxRetries: 5,
requireUnreliable: true,
transformDatagram: (data) => new TextDecoder().decode(data),
onDatagram: ({ message }) => {
const view = $scope["$ctrl"] as TelemetryController;
view.events = [...view.events, String(message)];
},
onReconnect: ({ connection }) => {
return connection.sendText(JSON.stringify({ subscribe: "telemetry" }));
},
});
}
send(value: string) {
return this.session.sendText(value);
}
}
The service expects the browser WebTransport API to exist and requires an
https: URL with an explicit port. The test backend exposes certificate hash
metadata at /webtransport/cert-hash for local browser tests.
Reconnect is opt-in at the service layer. When enabled, the
WebTransportConnection object stays stable while its native transport
instance is replaced. Use onReconnect as the renegotiation hook for
subscriptions, authentication messages, or other session state that the server
does not remember across HTTP/3 sessions.
For template-level feeds, ng-web-transport connects on load by default and
evaluates lifecycle expressions. data-mode="datagram" is the default;
data-mode="stream" reads server-opened unidirectional streams.
<div
ng-web-transport="transportUrl"
data-config="transportConfig"
data-mode="datagram"
data-transform="json"
data-as="session"
data-reconnect="true"
data-on-message="events.push($message)"
data-on-reconnect="reconnects = $attempt"
data-on-error="error = $error"
></div>
data-transform accepts bytes, text, or json. Message expressions receive
$connection, $data, $message, $event, and $text for text/json modes.
Reconnect is opt-in with data-reconnect="true"; tune it with
data-retry-delay and data-max-retries. data-on-reconnect runs after the
replacement session is ready and receives $attempt, $connection, $error,
and $url.
Web Workers
Use ng-worker when a view action should run CPU-heavy JavaScript outside the main thread.
<button
ng-worker="./workers/compress.js"
data-params="vm.fileBuffer"
data-on-result="vm.compressed = $result"
data-on-error="vm.error = $error"
trigger="click"
>
Compress
</button>
<span
ng-worker="./workers/sensor-reader.js"
interval="5000"
data-on-result="vm.sensorData = $result"
></span>
The directive evaluates data-params, posts the result to the worker, and exposes worker responses as $result in data-on-result. When no result expression is provided, it swaps the result into the element using the configured swap strategy.
A worker module receives values through self.onmessage and returns results through self.postMessage.
self.onmessage = function ({ data: { limit } }) {
const sieve = new Uint8Array(limit + 1).fill(1);
sieve[0] = sieve[1] = 0;
for (let i = 2; i * i <= limit; i++) {
if (sieve[i]) {
for (let j = i * i; j <= limit; j += i) sieve[j] = 0;
}
}
const primes = [];
for (let i = 2; i <= limit; i++) {
if (sieve[i]) primes.push(i);
}
self.postMessage(primes);
};
WebAssembly
ng-wasm loads a .wasm file and exposes its exports on the scope under a configurable name.
<div
ng-wasm
src="/wasm/image-processor.wasm"
as="imageProcessor"
></div>
const result = $scope.imageProcessor.grayscale(pixelBuffer, width, height);
WebAssembly loading is asynchronous. Guard calls until the export object exists or trigger work after the directive has linked.
Choosing A Transport
| Need | Use |
|---|---|
| Server pushes one-way updates | $sse |
| Client and server both send messages | $websocket |
| HTTP/3 datagrams or streams | $webTransport |
| CPU-heavy JavaScript | ng-worker |
| Compiled compute module | ng-wasm |
Related
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.