Groups

The groups allow to organize WebSocket connections and issue events to several sockets simultaneously.

A socket can belong to several groups. Membership is administered from the server and does not require the client to know the structure of the groups.

gox
socket.When("connect", func(isReconnect bool) {
    if err := socket.Join("announcements"); err != nil {
        socket.Disconnect(gox.WSCloseInternal)
    }
})

The groups are ephemeral. They are created when the first socket is added and disappear when they stop having members.

When the cluster is active, GOX automatically distributes the groups among all the instances of gox-server. Consultation Cluster configuration to know how to enable and configure this behavior.


Methods

MethodDescription
Join()Add the socket to a group.
Leave()It removes the socket from a group.
LeaveAll()It eliminates the socket of all its groups.
Groups()It returns the groups it belongs to.
EmitTo()It emits an event to the members of a group.

Join()

Firma:func (*Socket) Join(group string) error

Join() Add the current socket to the indicated group.

gox
if err := socket.Join("announcements"); err != nil {
    socket.Disconnect(gox.WSCloseInternal)
}

The socket must be connected before running Join(). Can be used from connect or from any subsequent event.

To add the same socket again to the same group does not duplicate its membership or make a mistake.

The group is automatically created if it does not yet exist.


Leave()

Firma:func (*Socket) Leave(group string) error

Leave() removes the current socket from the indicated group.

gox
if err := socket.Leave("announcements"); err != nil {
    socket.Disconnect(gox.WSCloseInternal)
}

Removing a socket from a group to which it does not belong does not make a mistake.

If the socket was the last member, the group automatically disappears.


LeaveAll()

Firma:func (*Socket) LeaveAll() error

LeaveAll() removes the current socket from all the groups to which it belongs.

gox
if err := socket.LeaveAll(); err != nil {
    socket.Disconnect(gox.WSCloseInternal)
}

Groups that remain empty automatically disappear.

GOX also eliminates the socket of all its groups when the connection ends. No need to run LeaveAll() before you disconnect it.


Groups()

Firma:func (*Socket) Groups() []string

Groups() returns the names of the groups to which the current socket belongs.

gox
groups := socket.Groups()

The result is an alphabetically ordered snapshot. Modifying the returned slice does not change the socket's membership.

When the socket does not belong to any group, it returns an empty slide.


EmitTo()

Firma:func (*Socket) EmitTo(group string, event string, values ...any)

EmitTo() send an event to all sockets belonging to the group.

gox
socket.EmitTo("announcements", "announcement", "Hola, George")

The socket that makes the issue does not need to belong to the group.

If you belong to the group, you also receive the event. EmitTo() does not automatically exclude the issuer.

The group may not exist or be empty. In that case, the operation does not produce any effect.

EmitTo() sends a normal event and does not expect responses from the members.

The values must be compatible with the JavaScript-Go communication system.


Names

The names of groups:

  • They can't be empty.
  • They can occupy up to 128 bytes.
  • They must contain valid UTF-8 text.
  • They can't start or end with spaces.
  • They cannot contain control characters.
  • Distinguish capital and lower capital.

For example, announcements and Announcements They represent different groups.

GOX retains the name exactly as provided and does not apply normalization.

Join() and Leave() They return a mistake when the name is not valid.


Global administration

The methods on this page manage groups from a specific connection.

To consult all active groups, access their members or issue events from code that does not depend on a particular socket, use the global record gox.Groups.

See Server groups to know their methods and the operations available by gox.SocketCollection.


Full example

The following example adds each socket to a group indicated during the handshake and distributes messages to its members.

Servidor:

gox
module websocket

import "github.com/gox-lang/gox"

func Index(socket *gox.Socket) gox.WebSocket {
    socket.When("connect", func(isReconnect bool) {
        room, exists := socket.Handshake.Query.Get("room")
        if !exists {
            socket.Disconnect(gox.WSClosePermanent)
            return
        }

        if err := socket.Join(room); err != nil {
            socket.Disconnect(gox.WSCloseInternal)
            return
        }

        socket.EmitTo(room, "memberJoined", socket.id())
    })

    socket.On("message", func(message string) {
        groups := socket.Groups()
        if len(groups) == 0 {
            return
        }

        socket.EmitTo(groups[0], "message", socket.id(), message)
    })

    socket.On("leave", func(group string) {
        if err := socket.Leave(group); err != nil {
            socket.Disconnect(gox.WSCloseInternal)
        }
    })
}

Cliente:

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

const socket = new Socket({
    query: {
        room: "general"
    }
})

socket.on("memberJoined", socketID => {
    console.log("Conectado:", socketID)
})

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

socket.emit("message", "Hola, George")

All sockets connected to room=general they belong to the same group and receive events issued by EmitTo().


Best practices

  • It uses short and descriptive names.
  • Keep a consistent convention to build dynamic names.
  • Check the errors returned by Join(), Leave() and LeaveAll().
  • It does not store permanent information only by group membership.
  • Do not depend on a group continuing to exist after it becomes empty.
  • Use socket.Groups() when you need to consult the membership of a connection.
  • Remember that the issuer also receives the event when it belongs to the group.
  • Do not use groups when each member has to produce a response.

To learn more about EventsSee your documentation. To learn more about RequestsSee your documentation. To learn more about Socket, check your documentation.


See also

Next step

Continue with Channels to learn to create spaces of communication with your own life cycle and behavior.

Channels