Skip to main content

Client API and events

Baseline: IOSignal JS 7.2.0, IOCore. Browser and Node.js clients share the core API but have different entry points.

EnvironmentImport
Node.jsimport { IO } from 'iosignal'
Browser bundlerimport IO from 'iosignal/browser/esm/io.js'

Create a client with new IO('ws://localhost:7777').

Methods​

SignaturePurpose and behavior
listen(tag, handler)Register a handler. Ordinary tags are saved for automatic subscription; direct @/@topic tags only register local listeners.
subscribe(tag) / unsubscribe(tag)Manually manage subscriptions. Subscribe after ready and repeat on reconnection. Direct-receive tags throw TypeError.
signal(tag, ...args) / publish(tag, ...args)Send a message. Payload types are selected from arguments. Sending does not confirm the recipient completed an action.
auth(id, key) / login(id, key)Configure authentication or log in on the current connection; see the authentication guide.
call(target, topic, ...args)Request a server service and receive a response Promise.
open(url?)Open or reopen a connection.
stop()Stop automatic reconnection and close the connection. The instance can be reopened.
destroy()Remove listeners and release resources. Do not reuse the instance.
link(component, tag, handler)Register a handler owned by a local component.
unlink(component, tag) / unlinkAll(component)Remove that component's linked handlers while respecting other subscription owners.

See payload formats, authentication, and subscription lifecycle.

Events​

EventMeaning
readyA CID is available and messaging can begin. Read io.cid or send manual subscriptions here.
changeConnection state name changed. Use it to update UI state.
messageChannel and CID-publication subscription messages, with (tag, ...args). Excludes direct messages.
@Every direct message addressed to this client, with (tag, ...args). The recipient CID is removed from the tag.
@topicAn exact direct topic, after the general @ event. No subscription needed.
errorConnection or processing errors.
Exact subscription tagHandle that subscription, such as room#chat or A@status. on() alone does not subscribe.

Avoid ordinary channel names such as ready, message, and error: library events and tag events share an event namespace.

Choose a subscription style​

on(tag, handler) registers a local listener. subscribe(tag) sends the server subscription. listen(tag, handler) combines listener registration with automatic subscriptions on connection and reconnection.

Automatic listen() subscriptions are sent after ready handlers run. If you must subscribe and immediately publish in a ready handler, call subscribe() first. See working examples.

Tag limits​

  • Tags are at most 255 UTF-8 bytes, not JavaScript characters.
  • signal()/publish(), getSignalPack(), and signal_e2e() throw TypeError for oversized tags. listen()/link()/unlink() also check lengths and reject empty tags.
  • Comma-separated lists passed to manual subscribe() or unsubscribe() must fit within 255 bytes as a whole. Split larger lists in application code. An invalid unsubscribe request does not change the saved list.
  • Automatic subscriptions are validated and split at tag boundaries into packets of at most 255 bytes. Strings and UTF-8 characters are not split internally.
  • CID publications must fit after the server adds the sender CID. The client validates when the CID is known; the server also validates the expanded tag. Oversized messages are neither delivered nor retained. Ordinary signal() does not acquire a server-error response Promise.

The wire length field remains one byte.

Direct and subscription delivery​

// Register handlers before messages arrive.
io.on('message', (tag, ...args) => {
console.log('Subscription:', tag, args);
});
io.on('@', (tag, value) => {
if (tag === '@set') console.log('Direct command:', value);
});
io.on('ready', () => {
io.subscribe('room#chat,A@status'); // Replace A with the publisher CID.
});

For one exact direct topic, use this instead of processing the same command in the general @ handler:

io.listen('@set', (tag, value) => {
console.log(tag, value);
});

on() and listen() both accept @ and @topic without a server subscription. Do not call subscribe('@topic') or unsubscribe('@topic'); they throw TypeError. A comma list containing any direct-receive tag is rejected as a whole. A@topic is a valid CID-publication subscription.

In 7.2.0, @ fires synchronously before the exact @topic event. A topicless @ fires only once. Direct messages never emit message. Subscribing to A@status produces A@status and message events as before.

Returning false does not cancel subsequent events, and async handlers are not awaited. Objects and binary arguments are shared, so mutations can be visible to later handlers. A synchronous exception is logged by the receive-path catch and stops the remaining delivery.

Do not manually forward the common @ event with emit(tag, ...): the exact topic event is already emitted. Arduino invokes onMessage once for a direct packet.

Cleanup​

Call destroy() when a component exclusively owning an IO instance is removed. If the IO instance is shared, use that component's unlinkAll(component) or remove its own listeners. See component ownership and version compatibility.