Client

The module @gox/websocket provides the object Socket used to establish and manage a WebSocket connection from JavaScript or TypeScript.

js
import { Socket } from "@gox/websocket"

const socket = new Socket()

new Socket() Start the connection immediately. By default, use the same source of the page and the endpoint WebSocket administered by GOX.

The client API and the server API are part of the same communication system. The client uses JavaScript and the server uses Go, but both record and issue the same events.

text
Cliente                         Servidor

socket.when(...)                socket.When(...)
socket.on(...)                  socket.On(...)
socket.emit(...)                socket.Emit(...)
socket.disconnect(...)          socket.Disconnect(...)

Structure

The object Socket provides the following main API:

text
Socket
{
    state string
    Channel

    when(event string, handler Function) Socket
    on(event string, handler Function) Socket
    emit(event string, ...values any) Promise<any>
    disconnect(code number) Socket
}
APIDescription
stateIt indicates the current state of the connection.
ChannelIt allows to create channels over the connection.
when()It records life cycle events.
on()It records events sent by the server.
emit()Send events to the server.
disconnect()It deliberately closes the connection.

Create a connection

The non-option builder uses the same origin of the page:

js
const socket = new Socket()

It can also be connected to another source:

js
const socket = new Socket({
    origin: "https://api.example.com"
})

GOX automatically determines the handshake protocol and route. It is not necessary to create a native instance of WebSocket nor to manually build your URL.

Each instance of Socket represents an independent connection.


state

Tipo:string

state contains the current state of connection:

ValueDescription
"connecting"The initial connection is being established.
"connected"The connection is available.
"reconnecting"GOX is waiting or trying to reconnect.
"disconnected"The connection's closed.
js
if (socket.state === "connected") {
    console.log("Socket disponible")
}

The property is read only. To react to state changes, use when().


when()

when() records events related to the socket life cycle.

js
socket.when("connect", isReconnect => {
    console.log("Conectado", { isReconnect })
})

socket.when("disconnect", details => {
    console.log("Desconectado", details)
})

socket.when("error", error => {
    console.error(error)
})

The main events are:

EventDescription
"connect"The connection is available.
"disconnect"The connection was closed.
"error"There was an operational or protocol error.

The server uses the same concept by When():

gox
socket.When("connect", func(isReconnect bool) {
    socket.Emit("welcome", "Hola, George")
})

Recording the same event replaces your previous handler.

See Lifecycle to know the reconnection, errors and closing codes.


on()

on() records an event sent by the server.

Servidor:

gox
socket.Emit("welcome", "Hola, George")

Cliente:

js
socket.on("welcome", message => {
    console.log(message)
})

The values are delivered in the same order in which they were issued:

gox
socket.Emit("profileUpdated", "George", true)
js
socket.on("profileUpdated", (name, active) => {
    console.log({ name, active })
})

In the opposite sense, the server uses On() to record the events sent by the client.

Recording the same event replaces your previous handler.


emit()

emit() send an event to the server:

js
socket.emit("greeting", "George")

The server receives the event by On():

gox
socket.On("greeting", func(name string) {
    log.Printf("Hola, %s", name)
})

You can provide one or more values:

js
socket.emit("updateProfile", "George", true)

The values must correspond to the handler parameters recorded on the server.

Responses

emit() returns a promise:

js
await socket.emit("updateProfile", "George", true)

When the server handler is signed with gox.EventReply and returns a value, the promise is resolved with that value:

gox
socket.On("greeting", func(name string) gox.EventReply {
    return "Hola, " + name
})
js
const message = await socket.emit("greeting", "George")
console.log(message)

If the handler does not use gox.EventReply, the promise is resolved with undefined after processing the event.

Forms

emit() You can also receive a full form:

js
const form = document.querySelector("#profile")

await socket.emit("updateProfile", form)

GOX uses the handler parameter names to locate the corresponding controls within the form:

gox
socket.On("updateProfile", func(name string, age int) {
    // ...
})

The controls may also be sent individually:

js
const name = document.querySelector("#name")
const age = document.querySelector("#age")

await socket.emit("updateProfile", name, age)

When individual controls are provided, your order must match the order of the handler parameters.

See Events, Requests and Values to know these behaviors in more detail.


disconnect()

disconnect() It deliberately closes the connection:

js
socket.disconnect()

You can also receive a closing code:

js
import { Socket, WSCloseCode } from "@gox/websocket"
const socket = new Socket()
socket.disconnect(WSCloseCode.PERMANENT)

The server can close the same connection by Disconnect():

gox
socket.Disconnect(gox.WSClosePermanent)

A disconnection requested directly by the client does not start an automatic reconnection.

See Lifecycle to know the available codes and their behavior.


Channel

Channel allows to create an isolated communication on the existing connection:

js
const chat = new socket.Channel("Chat")

The channel shares the transport of the socket, but maintains its own events and life cycle.

js
chat.when("connect", isReconnect => {
    console.log("Canal conectado", { isReconnect })
})

chat.on("message", message => {
    console.log(message)
})

chat.emit("message", "Hola")

See Channels to know your full API.


Best practices

  • It creates a single shared instance when several areas of the page use the same connection.
  • Search the handlers immediately after creating the socket.
  • Manage the event error.
  • It uses the closing codes provided by GOX.
  • Keep the arguments of emit() aligned with the server handler signature.
  • It uses channels to separate functionalities over the same connection.
  • Don't manually build the handshake URL.
  • Do not access the internal WebSocket transport directly.

To learn more about Socket, check your documentation.


See also

Next step

Continue with Lifecycle to know the connection, the reconnection, the errors and the closing codes.

Lifecycle