TypeScript Client Library
The Virtufin WebSocketManager TypeScript client library (virtufin-websocketmanager) provides a TypeScript interface for managing external WebSocket connections using gRPC-web and Connect-RPC.
Installation
From Gitea npm Registry
Configure authentication with a Gitea personal access token (scope: read:packages):
echo "//npm.haenerconsulting.com/api/packages/virtufin/npm/:_authToken=<your-gitea-token>" >> ~/.npmrc
Then install:
npm install virtufin-websocketmanager
From Local Source
{
"dependencies": {
"virtufin-websocketmanager": "file:path/to/src/typescript"
}
}
Overview
The client library provides the WebSocketManagerClient class as the main entry point for WebSocket connection management.
Quick Start
import { WebSocketManagerClient } from "virtufin-websocketmanager";
const client = new WebSocketManagerClient({ url: "http://localhost:5001" });
// Connect to a WebSocket server
const { id: connectionId, status } = await client.connect({
url: "wss://echo.websocket.org",
autoReconnect: false
});
console.log(`Connected: ${connectionId} - ${status}`);
// List all connections
const { connections } = await client.list({});
console.log(`Total connections: ${connections.length}`);
// Send a message
const { response } = await client.send({
id: connectionId,
message: JSON.stringify({ type: "ping" }),
timeoutMs: 5000
});
console.log(`Response: ${response}`);
// Disconnect
await client.disconnect({ id: connectionId });
WebSocketManagerClient
Constructor
const client = new WebSocketManagerClient({ url: string, timeout?: number });
Parameters:
- url - The gRPC-web base URL (e.g., "http://localhost:5001")
- timeout - Request timeout in milliseconds (default: 30000)
Methods
Connection Management
// Connect to a WebSocket server
connect(request: ConnectRequest): Promise<ConnectResponse>
// Disconnect from a WebSocket server
disconnect(request: DisconnectRequest): Promise<DisconnectResponse>
// List all managed connections
list(request: ListRequest = {}): Promise<ListResponse>
Example:
const { id: connectionId, status } = await client.connect({
url: "wss://echo.websocket.org",
autoReconnect: true
});
const { connections } = await client.list({});
for (const conn of connections) {
console.log(`${conn.id}: ${conn.url} [${conn.status}]`);
}
await client.disconnect({ id: connectionId });
Pub/Sub Integration
// Start publishing WebSocket messages to a Dapr pub/sub topic
startPublish(request: StartPublishRequest): Promise<StartPublishResponse>
// Stop publishing to the topic
stopPublish(request: StopPublishRequest): Promise<StopPublishResponse>
Example:
await client.startPublish({
id: connectionId,
topic: "websocket-events"
});
await client.stopPublish({ id: connectionId });
Messaging
// Send a message and wait for a correlated response
send(request: SendRequest): Promise<SendResponse>
// Send a message without waiting for a response
sendRaw(request: SendRawRequest): Promise<SendRawResponse>
Example:
// Send with correlation (expects response)
const { response } = await client.send({
id: connectionId,
message: JSON.stringify({ type: "request", id: "123" }),
timeoutMs: 5000
});
console.log(`Response: ${response}`);
// Fire-and-forget
await client.sendRaw({
id: connectionId,
message: JSON.stringify({ type: "notification" })
});
Data Models
ConnectRequest
interface ConnectRequest {
url: string;
autoReconnect?: boolean;
}
ConnectResponse
interface ConnectResponse {
id: string;
status: string;
}
WebSocketConnection
interface WebSocketConnection {
id: string;
url: string;
status: string;
topic: string;
instanceId: string;
}
SendRequest
interface SendRequest {
id: string;
message: string;
timeoutMs: number;
}
SendResponse
interface SendResponse {
response: string;
}
Error Handling
Connection Not Found
try {
await client.disconnect({ id: "nonexistent" });
} catch (error) {
if (error instanceof ConnectError) {
console.log(`Not found: ${error.message}`);
}
}
Send Timeout
try {
const { response } = await client.send({
id: connectionId,
message: "slow request",
timeoutMs: 100 // very short
});
} catch (error) {
if (error instanceof ConnectError && error.code === Code.DeadlineExceeded) {
console.log("Send timed out");
}
}
Connection Errors
try {
const client = new WebSocketManagerClient({ url: "http://invalid-host:5001" });
await client.connect({ url: "wss://invalid" });
} catch (error) {
console.log(`Connection failed: ${error.message}`);
}
Complete Example
import { WebSocketManagerClient } from "virtufin-websocketmanager";
async function main() {
console.log("WebSocketManager Client Demo");
console.log("==============================\n");
const client = new WebSocketManagerClient({ url: "http://localhost:5001" });
// Connect
console.log("Connecting to WebSocket server...");
const { id: connectionId, status } = await client.connect({
url: "wss://echo.websocket.org",
autoReconnect: false
});
console.log(`Connected: ${connectionId} - ${status}`);
// List connections
console.log("\nAll connections:");
const { connections } = await client.list({});
for (const conn of connections) {
console.log(` ${conn.id}: ${conn.url} [${conn.status}]`);
if (conn.topic) {
console.log(` Publishing to: ${conn.topic}`);
}
}
// Send a message
console.log("\nSending message...");
const { response } = await client.send({
id: connectionId,
message: JSON.stringify({ type: "request", id: "123", data: "hello" }),
timeoutMs: 5000
});
console.log(`Response: ${response}`);
// Start pub/sub
console.log("\nStarting pub/sub...");
await client.startPublish({
id: connectionId,
topic: "ws-events"
});
console.log("Publishing started");
// Stop pub/sub
console.log("\nStopping pub/sub...");
await client.stopPublish({ id: connectionId });
console.log("Publishing stopped");
// Disconnect
console.log("\nDisconnecting...");
await client.disconnect({ id: connectionId });
console.log("Disconnected");
}
main();
Protobuf Dependencies
The client library requires the peer dependency:
{
"peerDependencies": {
"@bufbuild/protobuf": "^1.10.0"
}
}
Ensure your project installs the peer dependency:
npm install @bufbuild/protobuf
The proto files are pre-compiled into the src/generated directory.
Generated Protos
The client includes generated protobuf classes from websocketmanager.proto:
| Type | Description |
|---|---|
ConnectRequest |
Request to connect to a WebSocket server |
ConnectResponse |
Response with connection ID and status |
ListRequest |
Request to list all connections |
ListResponse |
Response with list of connections |
DisconnectRequest |
Request to disconnect |
DisconnectResponse |
Empty response |
StartPublishRequest |
Request to start pub/sub publishing |
StartPublishResponse |
Empty response |
StopPublishRequest |
Request to stop publishing |
StopPublishResponse |
Empty response |
SendRequest |
Request to send a correlated message |
SendResponse |
Response with server reply |
SendRawRequest |
Request to send without waiting |
SendRawResponse |
Empty response |
WebSocketConnection |
Connection details |
| ## SDK Reference |