PHPackages                             spiral/websocket-client - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. spiral/websocket-client

ArchivedLibrary

spiral/websocket-client
=======================

Websocket JS Client

v0.0.4(5y ago)74[4 PRs](https://github.com/spiral-modules/websocket-client/pulls)MITTypeScript

Since Mar 12Pushed 2y ago6 watchersCompare

[ Source](https://github.com/spiral-modules/websocket-client)[ Packagist](https://packagist.org/packages/spiral/websocket-client)[ RSS](/packages/spiral-websocket-client/feed)WikiDiscussions master Synced 6d ago

READMEChangelog (1)DependenciesVersions (7)Used By (0)

Spiral Framework WebSocket
==========================

[](#spiral-framework-websocket)

JavaScript WebSockets client library with channel support.

Since RoadRunner 2.x, the communication protocol has been changed. Below is a table of version compatibility.

RoadRunnerspiralscout/websockets1.0+0.0.1+2.3+0.1.0+Installation
------------

[](#installation)

SFSocket available for installing with npm or yarn

```
    npm install @spiralscout/websockets -D
```

```
    yarn add @spiralscout/websockets
```

Next use it like so

```
    import { SFSocket } from '@spiralscout/websockets';
```

Or via bundle file

```

        var Socket = SFSocket.SFSocket;
        var connection = new Socket({ host: 'localhost'});

```

If you prefer CDN usage, use following URL for most recent version

```
https://cdn.jsdelivr.net/gh/spiral/websockets/build/socket.js

```

API
---

[](#api)

SFSocket proposes easy way to use WebSockets:

```
import { SFSocket } from '@spiralscout/websockets';

const socketOptions = { host: 'localhost' };

// create an instance of SFSocket
const ws = new SFSocket(socketOptions);

const prepareEvent = event => doSomething(event);

// subscribe to server
ws.subscribe('message', prepareEvent);

// runtime ready for all instances
SFSocket.ready();

// unsubscribe from server
ws.unsubscribe('message', prepareEvent);

// disconnect from server
ws.disconnect();
```

### SFSocket

[](#sfsocket)

   SFSocket    **Properties**     `static instances`   `SFSocket[]`
 Array of all existing sockets     `static isReady`   `boolean`
 false before `ready()` is called. If is true any new SFSocket will connect upon creation.     **Methods**     `static ready()`   Marks sockets as ready and launches all connections.
 Use if you need to make all sockets to connect automatically on creation     `constructor(options: ISFSocketConfig)`   Create websocket connection
 `options: ISFSocketConfig` - connection options     `joinChannel(channel, dontJoin)`   Creates a named channel and joins it
 `channel: string` name of channel to join. Should NOT be one of system ones: `@join`, `#join`, `@leave`, `#leave`
 `dontJoin: boolean` **default false** if true, channel is created, registered inside instance but not joined automatically. Call `join` method to join later.
 `return value: Channel` returns channel object     `getChannel(channel)`   Gets a previously created named channel
 `return value: Channel` returns channel object     `leaveChannel(channel)`   Removes a named channel and leaves it
 `channel: string` name of channel to join. Should NOT be one of system ones `@join`, `#join`, `@leave`, `#leave`
 `return value: Channel` returns channel object     `subscribe(event, callback, channel)`   Subscribes to specific event
 `event: string` one of valid event codes. See table below for possible events and their payload
 `callback: (payload) => void` callback to call. Type of payload depends on event type
 `channel: string` (optional) Channel name to follow. If none, subscribes for all. Note that doesn't automatically join channel, just adds listener to existing one.     `unsubscribe(event, callback, channel)`   Unsubscribes from specific event
 `event: string` one of valid event codes. See table below for possible events and their payload
 `callback: (payload) => void` callback to call. Type of payload depends on event type
 `channel: string` (optional) Channel name to unfollow. If none, unsubscribes from all channels. Note that doesn't automatically remove channel, just removes listener from existing one.   ### SFSocket constructor options

[](#sfsocket-constructor-options)

SFSocket supports standard (ws) and secure (wss) protocols.

SFSocket constructor `new SFSocket(options: ISFSocketConfig)` is expecting options of type `ISFSocketConfig`

   ISFSocketConfig    `host`   `string`
 Host websocket should connect to     `port`   `string` or `number`
 (optional) Port websocket should connect to
 **Default**: 80 or 443 if useTSL = true     `useTSL`   `boolean`
 (optional) Use TSL `wss` instead of regular `ws` protocol
 **Default**: false     `path`   `string`
 (optional) Server path part
 **Default**: empty     `queryParams`   `object` of `{[key: string]: string}` type
 (optional) Query params map to append to path
 **Default**: empty     `unavailableTimeout`   `number`
 (optional) A timeout which is considered to be large enough to stop retrying reconnects if server response takes longer
 **Default**: 10000   For example to establish connection to `ws://some.domain.com/foo?bar=1` use following code

```
import { SFSocket } from '@spiralscout/websockets';

const socketOptions = {
  host: 'some.domain.com',
  port: '80',
  path: 'foo',
  queryParams: { bar: '1' }
}

const ws = new SFSocket(socketOptions);
```

### SFSocket channels

[](#sfsocket-channels)

   Channel    **Properties**     `status`   `string` Channel status, can be `closed`, `joinin`, `joined`, `leaving` or `error`     `name`   `string` Channel name     **Methods**     `constructor(name: string, socket: SFSocket)`   Creates a channel based on specific SFSocket
 `name: string` - channel name. Can NOT be `@join`, `#join`, `@leave`, `#leave`     `join()`   Enables channel and sends join command once connection is working     `leave()`   Disables channel and sends leave command if connection is working     `subscribe(event, callback)`   Subscribes to specific event
 `event: string` one of valid event codes. See table below for possible events and their payload
 `callback: (payload) => void` callback to call. Type of payload depends on event type
     `unsubscribe(event, callback)`   Unsubscribes from specific event
 `event: string` one of valid event codes. See table below for possible events and their payload
 `callback: (payload) => void` callback to call. Type of payload depends on event type
     `connect()`   Starts connection. This method is automatically called after `SFSocket.ready()` for all existing and new instances     `disconnect()`   Drops connection   ### Supported events

[](#supported-events)

`SFSocket` and `Channel` make it possible to subscribe to `connected`, `message`, `closed` and `error` events

`SFSocket` additionally allows to subscribe to `channel_joined`, `channel_join_failed` and `channel_left` events

   Events    `message`   `ISFSocketEvent`
 Generic event of message from specific channel or broadcasted Payload depends on channel server implementation     `error`   `ISFSocketEvent`
 Event of error happened in specific channel or broadcasted Payload would contain error details     `closed`   `ISFSocketEvent`
 Connection was closed due some error. Socket might automatically reconnect after that.     `channel_joined`   `string[]`
 Indicates server confirming joining specific channels     `channel_left`   `string[]`
 Indicates server confirming leaving specific channels     `channel_join_failed`   `string[]`
 Indicates server denies joining specific channels   ### ISFSocketEvent structure

[](#isfsocketevent-structure)

   ISFSocketEvent    `type`   `string`
 `sfSocket:message`, `sfSocket:closed` or `sfSocket:error` depending on event tracked.     `data`   `any`
 Any serializable payload depending on implementation that refers to successful flow     `error`   `string`
 Error message     `context`   `object`
 Object with event context details     `context.code`   `number`
 Error code if relevant     `context.channel`   `string`
 Channel name if relevant   ##### Message Event

[](#message-event)

```
const MessageEvent: ISFSocketEvent = {
  context: {
    channel: 'channel', // optional
    code: 1001, // optional
  },
  data: 'message',
  error: null,
  type: 'sfSocket:message',
};
```

##### Error Event

[](#error-event)

```
const ErrorEvent: ISFSocketEvent = {
  context: {
    channel: 'channel', // optional
    code: 1006, // optional
  },
  data: null,
  error: 'message',
  type: 'sfSocket:error',
};
```

### Samples

[](#samples)

Working with events

```
const ws = new SFSocket(socketOptions);

ws.subscribe('connected', () => console.log('connected'));
ws.subscribe('error', (sfSocketEvent) => doSomething(sfSocketEvent));
ws.subscribe('message', (sfSocketEvent) => doSomething(sfSocketEvent));
ws.subscribe('closed', () => console.log('closed'));

const channel = ws.joinChannel('topic1');

channel.subscribe('connected', () => console.log('connected'));
channel.subscribe('error', (sfSocketEvent) => doSomething(sfSocketEvent));
channel.subscribe('message', (sfSocketEvent) => doSomething(sfSocketEvent));
channel.subscribe('closed', () => console.log('closed'));
```

Multiple channels creation

```
import { SFSocket } from '@spiralscout/websockets';

const socketOptions = { host: 'localhost' };

const ws = new SFSocket(socketOptions);

SFSocket.ready();

// create a channel and it is automatically connected to server
const channel1 = ws.joinChannel('channel_1');
const channel2 = ws.joinChannel('channel_2', true); // This one wont auto-join now

// subscribe the channel to server
channel1.subscribe('message', (event) => doSomething(event));
channel2.subscribe('message', (event) => doSomething(event));

channel2.join(); // Start receiving messages for channel2

// disconnect the channel from server
channel1.leave();
channel2.leave();

// disconnect everything
ws.disconnect()
```

### Custom commands

[](#custom-commands)

Sending custom commands is supported via `sendCommand` method. `join` and `leave` commands can NOT be used as command name, payload can be any serializable data.

```
const cmd = 'foo'; // Any string except 'join' or 'leave'
const data = ['bar']; // Serializable data
ws.sendCommand(cmd, data);
```

Development
-----------

[](#development)

##### Prerequisites

[](#prerequisites)

- [nodejs](https://nodejs.org/en/) 10.16.3+
- [yarn](https://yarnpkg.com/lang/en/) 1.19.1+

##### Windows

[](#windows)

On windows execute `git config core.autocrlf false` to disable automatic line ending conversion.

###  Health Score

25

—

LowBetter than 37% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity9

Limited adoption so far

Community14

Small or concentrated contributor base

Maturity50

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 66.7% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~220 days

Total

2

Last Release

2037d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/796136?v=4)[Anton Tsitou](/maintainers/wolfy-j)[@wolfy-j](https://github.com/wolfy-j)

---

Top Contributors

[![AndrewKirkovski](https://avatars.githubusercontent.com/u/16134699?v=4)](https://github.com/AndrewKirkovski "AndrewKirkovski (36 commits)")[![SerafimArts](https://avatars.githubusercontent.com/u/2461257?v=4)](https://github.com/SerafimArts "SerafimArts (11 commits)")[![Kreezag](https://avatars.githubusercontent.com/u/13301570?v=4)](https://github.com/Kreezag "Kreezag (4 commits)")[![askd](https://avatars.githubusercontent.com/u/1499345?v=4)](https://github.com/askd "askd (2 commits)")[![wolfy-j](https://avatars.githubusercontent.com/u/796136?v=4)](https://github.com/wolfy-j "wolfy-j (1 commits)")

### Embed Badge

![Health badge](/badges/spiral-websocket-client/health.svg)

```
[![Health](https://phpackages.com/badges/spiral-websocket-client/health.svg)](https://phpackages.com/packages/spiral-websocket-client)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
