Web quickstart
Install exactly easyjssdk 2.0.4 and use a product BFF plus contiguous TypeScript code for an online browser messaging loop.
The browser asks the product BFF for the current user's connection material, then EasyJSSDK establishes a WebSocket JSON-RPC connection. The client holds no Product HTTP management credential, and Alice and Bob accept the path in two isolated browser contexts.
The current Product Gateway supports this connection path
The current Product Gateway supports pinned v2.0.4 JSON-RPC CONNECT and online bidirectional messaging, including requests without jsonrpc, Base64 SEND, and object RECV. Browsers default to WEB 1; the full wire set is APP 0, WEB 1, and PC 2. The tutorial installs npm 2.0.4. The official browser example passed at source revision a055b3667247333b6b3183249f5d5929673dfd53, which is now included in the v2.0.4 Release. The npm artifact then completed bidirectional messaging and disconnect in Chrome 151 and hosted released-package peer runs.
What you will have
- An npm dependency pinned to
easyjssdk@2.0.4. - A browser client that consumes only a minimal product-BFF response.
- Event callbacks that can be removed precisely with
off, plus page-exit cleanup. - Two independent observations: Alice's send result and Bob's realtime receive.
Run the official example first (recommended)
Check out the exact source to reproduce the verified path:
git clone https://github.com/WuKongIM/WuKongEasySDK-JS.git
cd WuKongEasySDK-JS
git checkout a055b3667247333b6b3183249f5d5929673dfd53
npm ci
npm test
npm run build
python3 -m http.server 8080Open http://127.0.0.1:8080/example/. Run the Official Examples covers WuKongIM startup, Alice/Bob preparation, and endpoint mapping. The source example and npm 2.0.4 artifact now have separate runtime receipts; keep those evidence classes distinct.
Before you begin
Prepare the following:
- A modern browser with native WebSocket,
TextEncoder, andTextDecoder. - A WuKongIM single-node cluster or multi-node cluster whose
/readyzis healthy and whose WebSocket Gateway is browser-reachable. - A same-origin product BFF, or one with a deliberately configured cross-origin policy.
- A BFF that validates the product session and returns
uid, a short-livedtoken, andwebsocketUrlfor the current user.
Read Identity & Token first. Production pages and WebSockets use HTTPS/WSS, and tokens never belong in URLs, Local Storage, logs, or analytics events.
Step 1: install an exact version
Run this in an existing Vite, Next.js, or other bundled application:
npm install --save-exact easyjssdk@2.0.4Commit package-lock.json. This tutorial does not use a floating CDN version that could silently replace the SDK after a page refresh.
Step 2: obtain connection material from the product BFF
/api/im/bootstrap below is your product route, not WuKongIM Product HTTP. The BFF validates the server-side login session, issues a short-lived token, and safely selects the WebSocket address returned by /route:
interface IMBootstrap {
uid: string;
token: string;
websocketUrl: string;
}
async function fetchIMBootstrap(): Promise<IMBootstrap> {
const response = await fetch('/api/im/bootstrap', {
credentials: 'include',
cache: 'no-store',
headers: { accept: 'application/json' },
});
if (!response.ok) throw new Error(`IM bootstrap failed: ${response.status}`);
return response.json() as Promise<IMBootstrap>;
}The browser never calls /user/token or /route directly. Their management boundary, server credential, and response filtering remain inside the BFF.
Step 3: initialize, subscribe, and connect
on receives a function reference; off must receive the same reference. This example disables global-singleton mode so hot reload, tests, or a multi-instance page cannot silently destroy another client:
import { WKIM, WKIMChannelType, WKIMEvent } from 'easyjssdk';
export class EasyChatClient {
private im?: WKIM;
private readonly messages = new Map<string, unknown>();
private readonly onConnect = (_result: unknown) => {
console.info('EasySDK connected');
};
private readonly onDisconnect = (_info: unknown) => {
console.info('EasySDK disconnected');
};
private readonly onMessage = (message: any) => {
if (this.messages.has(message.messageId)) return;
this.messages.set(message.messageId, message);
// Pass the deduplicated message to application state.
};
private readonly onError = (_error: unknown) => {
console.error('EasySDK operation failed');
};
async start(bootstrap: IMBootstrap): Promise<void> {
this.stop();
const im = WKIM.init(
bootstrap.websocketUrl,
{ uid: bootstrap.uid, token: bootstrap.token },
{ singleton: false, debugLogging: false },
);
im.on(WKIMEvent.Connect, this.onConnect);
im.on(WKIMEvent.Disconnect, this.onDisconnect);
im.on(WKIMEvent.Message, this.onMessage);
im.on(WKIMEvent.Error, this.onError);
this.im = im;
await this.connectWithin(im, 10_000);
}
private async connectWithin(im: WKIM, timeoutMs: number): Promise<void> {
let timeout: ReturnType<typeof setTimeout> | undefined;
try {
await Promise.race([
im.connect(),
new Promise<void>((_, reject) => {
timeout = setTimeout(
() => reject(new Error(`EasySDK connect exceeded ${timeoutMs} ms`)),
timeoutMs,
);
}),
]);
} catch (error) {
im.destroy();
if (this.im === im) this.im = undefined;
throw error;
} finally {
if (timeout) clearTimeout(timeout);
}
}
async sendText(targetUid: string, text: string) {
if (!this.im?.isConnected) throw new Error('EasySDK is not connected');
return this.im.send(targetUid, WKIMChannelType.Person, {
type: 1,
version: 1,
content: text,
});
}
stop(): void {
const im = this.im;
if (!im) return;
im.off(WKIMEvent.Connect, this.onConnect);
im.off(WKIMEvent.Disconnect, this.onDisconnect);
im.off(WKIMEvent.Message, this.onMessage);
im.off(WKIMEvent.Error, this.onError);
im.destroy();
this.im = undefined;
}
}debugLogging: false matches the SDK default and is written explicitly here so production configuration can be reviewed. Set it to true only during a controlled diagnostic window; the SDK still emits only sanitized operational metadata, and application callbacks or collectors must not log complete events, results, or payloads.
An application normally creates one EasyChatClient. The SDK has an internal timeout for the CONNECT JSON-RPC request, but the WebSocket-open phase can still hang; connectWithin bounds the complete wait at 10 seconds and calls destroy after failure. React can keep the client in a root-level Provider and call stop() from an Effect cleanup. Vue and Svelte use the corresponding component or application unmount hook.
Step 4: send the first message
const chat = new EasyChatClient();
const alice = await fetchIMBootstrap();
await chat.start(alice);
await chat.sendText('bob', 'Hello from Web EasySDK');
console.info('SEND completed');
window.addEventListener('pagehide', () => chat.stop(), { once: true });Alice's resolved Promise means the send request received a server result. Bob must still observe the message in an independent page through WKIMEvent.Message. Do not render Alice's send result as proof that Bob read or processed it.
Step 5: accept with Alice and Bob
- Open two independent browser profiles or isolated browser contexts and sign in as Alice and Bob.
- Both sides obtain connection material from their own product session and observe
WKIMEvent.Connect. - Have Alice send to the person Channel
bob, retaining the send result. - On Bob, verify
fromUid,channelId,messageId, and payload. - Have Bob send back to Alice and prove the reverse direction.
- Use an unreachable address and confirm failure plus
destroywithin 10 seconds, rather than leaving the page in Connecting forever. - Refresh, close, or sign out and confirm that the old instance called
offanddestroy, leaving no duplicate connection.
That exact source ran against the same WuKongIM revision in Chrome 151 and completed bidirectional messaging, manual disconnect, and reconnect. The npm 2.0.4 artifact also completed bidirectional messaging, SENDACK, and disconnect in real Chrome and hosted released-package peer runs. The loop still does not cover offline synchronization or production WSS. When Bob is offline, the application cannot wait only for an EasySDK realtime event; it needs a product-designed durable synchronization path.
Troubleshooting
- The page says WebSocket or encoding APIs are missing: confirm the browser and build environment provide WebSocket,
TextEncoder, andTextDecoder; do not infer Mini Program support from the browser path. - Connection is rejected before ready: inspect the BFF-returned WSS address, token lifetime, certificate, proxy Upgrade, and Gateway reachability.
- Messages duplicate after refresh: do not call
onduring every component render; retain callbacks and calloff/destroyduring unmount. - The console still contains a token or payload: first use the lockfile and browser bundle to confirm that
easyjssdk@2.0.4is actually shipped, then inspect application event callbacks, error handling, and collectors for complete-object logging. SDK diagnostics are off by default and should emit only sanitized operational metadata when explicitly enabled. Reproduce with the npm artifact and retain only low-sensitivity evidence before filing an issue. - You need an executable Web scenario path: use the WuKongIMJSSDK Web tutorial, which has the site's protected verification flow, and review the current build and runtime boundaries under API Versions & Compatibility. Do not mix method names between the two SDKs.
Before production
- Serve both the page and WebSocket over HTTPS/WSS, then verify certificates, proxy Upgrade, the BFF origin policy, and Gateway reachability.
- Return only the current session's connection material from the BFF; tokens never belong in URLs, Local Storage, logs, or analytics events.
debugLoggingis off by default. Keep itfalsein production and inspect the actual npm2.0.4bundle, Console, error reporting, and collectors with non-production canaries for tokens, payloads, raw frames, or complete event objects.- Retain the lockfile, browser and build versions, network, and server revision; separately verify refresh, logout, reconnect, and durable recovery while Bob is offline.
- Continue with Integration Acceptance for capacity, observability, upgrades, and rollback.
Next
Return to the WuKongEasySDK overview, or continue with Messaging, Offline Messages & Push, and the Release Checks.