WebSocket

Overview

Stellar uses Primus to work with WebSockets. Primus provides an abstraction layer over a WebSocket engine; it supports ws, engine.io, and socket.io, among others. WebSockets can use HTTP or HTTPS to connect to the server (HTTPS is recommended).

When Stellar starts, a script is generated with some useful functions to make the connection between the client and the server. This script can be obtained by accessing the URL http(s)://stellar_domain.com/stellar-client

Note: The newest versions of Stellar uses the new Fetch API to make HTTP requests to the server. This API isn’t supported by some old browsers, so in order to add support for then, you need to use a Polyfill.

Chat System

The client library already contains methods that make your file easier when you want to use the Stellar’s chat room system. This system works by events, so, each message has an event name and can also, optionally, contains extra data. This is excellent for games, dashboard or another kind of real-time feature. Down below you can see the structure of an event:

{
"event": "event_name",
"data": { "some": "data sent by the server" }
}

There is always a default room defined, this room is used when there is no room specified during a method call. You can define it using a parameter (defaultRoom), when constructing the StellarClient instance, calling the .setDefaultRoom(roomName) on the client, or on the server side, changind the servers.websocket.client.defaultRoom config value.

You can see all the available methods on the next section.

Methods

The generated client script contains a set of methods to start a real-time communication with the server, make calls to actions, send messages to chat rooms, and lots of others useful features. All those methods uses Promises that means you can get rid of the callback hell.

Note: in older browsers you will need load a polyfill in order to this work properly.

The following methods are provided to the client interact with the server:

Open Connection

The client.connect() method allows a client to open a connection with the server.

Call an Action

The client.action(action, params = {}) method allows a client to invoke an action:

Note: When an open WebSocket connection does not exist, the client will fall back to HTTP.

The following example shows how do you can use the async/await syntax to perform an action call to make login:

try {
// try make login
const { user } = await client.action('auth.signin', { email, password })

console.log('Logged in with', user)
} catch (e) {
console.log('Wrong credentials')
}

Send Messages

The .say(room, message) method allows a client to send a message to a chat room. This method is just an alias to send a message event.

Note: you need use the roomAdd method before you can interact with a chat room.

// send a message to the default room
stellar.say([ 'can', 'be', 'any', 'type' ])

// send a message to a specific room
stellar.say('room_name', [ 'can', 'be', 'any', 'type' ])

Details

The .detailsView() method allows you to get details about the client connection.

Note: the first response of the detailsView method is stored to be used in the future.

Emit Event

In order to emit an event into a chat room you must use the .emit(eventName, data). When this method is executed alone the event is sent to the default room.

// send an event to the default room
client.emit('performAction', { action: 'attack1', position })

To complement this you can specify here the event must be emitted using the .for(roomName) method. This method can be chained together as many times as you want in order to apply more filters to the event, or you can simply pass an array as an argument.

// send an event to a specific room
client.for('world01').emit('performAction', { action: 'attack1', position })

Handle Events

The .on(eventName, handler) method allows you to catch and event and do something with it.

// this catch the `newPosition` event, that can be emitted in any room
client.on('newPosition', data => { })

To catch an event on a specific room to can use the .to(roomName) method. This method can be chained together as many times as you want in order to apply more filters to the event, or you can simply pass an array as an argument.

// this catch the `newPlayer` event but only if this one was emitted on
// the `world01` room.
client.to('world01').on('newPlayer', data => { })

Chat Room State

The .roomView(room) method allows you to obtain metadata for the requested chat room.

Join a Chat Room

The .join(room) method allows you to join to a chat room:

await client.join('awesomeRoom')

Leave a Chat Room

The .leave(room) allows you to leave a chat room:

Request a File

The client.file(file) method allows you request a static file from the server:

The response object has the following structure:

{
"content": "File Content...",
"context": "response",
"error": null,
"length" 20,
"messageCount" : 3,
"mime": "text/txt"
}

Disconnect

The client.disconnect() method allows you to disconnect the client from the server.

Events

The following list shows the events which are available to the client.

Connected

The connected event is triggered when the client connects to the server.

client.on('connected', () => { })

Disconnected

The disconnected event is triggered when the client disconnects from the server.

client.on('disconnected', () => { })

Error

The error event is triggered when an error occurs during a verb execution.

client.on('error', error => { })

Reconnect

The reconnect event occurs when the connection between the server and the client is temporarily interrupted.

client.on('reconnect', () => { })

Note: the connection details can be changed when a reconnect occurs.

Reconnecting

The reconnecting event occurs when the client tries to reconnect with the server.

client.on('reconnecting', () => { })

Message

The message event occurs when the client receives a new message.

client.on('message', message => { })

Warning: this event occurs every time the client receives a new message - this is a very noisy event.

Alert

The alert event occurs when the client receives a new message from the server with the alert context.

client.on('alert', message => { })

API

The api event occurs when the client receives a new message with an unknown context.

client.on('api', message => { })

Welcome

The welcome event occurs when the server sends a welcome message to the new-connected client.

client.on('welcome', message => { })

Say

Finally, the say event occurs when the client receives a new message from another client in the same room.

client.on('say', message => { })

Note: the message.room property allows you to get the message origin.

Interceptors

Interceptors can be used for pre- and post-processing a request. This is particularly useful for authentication and prevent unnecessary requests to the server, for some specific case. The follow examples shows different ways of using interceptors.

This example shows how to append or modify request’s parameters:

client.interceptors.push((params, next) => {
params.token = LocalStorage.getItem('token')

next()
})

Here we prevent the request to be send to the server returning an object as request’s response:

client.interceptors.push((params, next) => {
next({ someKey: 'someValue' })
})

In this next case we also prevent the request to happen but this time we return an error:

client.interceptors.push((params, next) => {
next(null, { message: 'Bad news! An error was occurred.' })
})

Finally, we can also change the server response passing a function to the next():

client.interceptors.push((params, next) => {
next(response => {
response.additionalField = 'Awesome call...'
})
})