[]
        
(Showing Draft Content)

Messages Sending and Receiving

js-collaboration facilitates bidirectional client-server communication while enabling server-initiated message broadcasting to all clients within a room. This documentation details the technical implementation of:

  • The client sends messages to the server

  • The server receives and responds to messages

  • Message broadcast

Basic Sending and Receiving

Client → Server

The client sends messages to the server using the connection.send() method. Message supports multiple data types, including strings, plain objects, numbers, and arrays.

// Client side
// Send a message to the server
connection.send('hello, world!');

The server can receive client messages through the message hook.

// Server side
server.on('message', ({ connection, data }) => {
    console.log('Received message from client:', data);
});

Server → Client

The client receives messages from the server using the connection.on('message') method.

//client side
connection.on('message', (data) => {
    console.log('Received message from server:', data);
});

The server sends messages to the client using the connection.send() method.

//server side
server.on('connect', ({ connection }) => {
    connection.send('hello, world!');
});

Server Broadcasting

The server can not only send messages to one client but also broadcast messages to all other clients in a room using the connection.broadcast() method.

Broadcast Messages Excluding the Sender

When only the roomId parameter is provided to connection.broadcast(), the default behavior is to broadcasting messages excluding the sender.

messages_sending_and_receiving-broadcast1

// Client side
connection.on('message', (data) => {
    console.log('Received message from server:', data);
});
// Server side
server.on('connect', ({ connection, roomId }) => {
    // When a client connects, broadcast a message to all clients in the room (excluding the sender)
    connection.broadcast(`${connection.id} join ${roomId}`);
});

Broadcast Messages Including the Sender

To broadcast messages to all room participants including the sender, configure the broadcast method with includeSelf: true.

messages_sending_and_receiving-broadcast2

// Client side
connection.on('message', (data) => {
    console.log('Received message from server:', data);
});// Client side
connection.on('message', (data) => {
    console.log('Received message from server:', data);
});
// Server side
server.on('connect', ({ connection, roomId }) => {
    // When a client connects, broadcast a message to all clients in the room (including the sender)
    connection.broadcast(`${connection.id} join ${roomId}`, '', true);
});

type=note

The second parameter of broadcast() is the message type (optional), which is an empty string in this case.

Message Types

Message types are used to identify the purpose or category of a message, allowing the receiver to determine whether the message is relevant to itself.

For example, in a collaboration scenario, the type could be "my-document" or "my-presence" to distinguish between document update messages and user status messages.

// Send a document update
connection.send({ content: 'New paragraph' }, 'my-document');
// Send an online status
connection.send({ userId: 'user1', active: true }, 'my-presence');
// Receive and distinguish messages
connection.on('message', (data, type) => {
    if (type === 'my-document') {
        console.log('Document update:', data);
    } else if (type === 'my-presence') {
        console.log('Status update:', data);
    }
});

Message Order

js-collaboration guarantees that messages are delivered in the order they were sent. For example:

connection.send('msg1');
connection.send('msg2');
connection.send('msg3');

The receiver will always receive the messages in the order: msg1, msg2, msg3.

Message Delivery

Delivery Guarantee

js-collaboration implements an ​​At-Most-Once Delivery​​ mechanism defined as:

  • If a message is sent while the connection is disconnected, the system cannot ensure that the recipient has received the message.

  • When reconnecting after a disconnection, previously undelivered messages will not be automatically resent.

Client Behavior

When the connection is disconnected, the client adopts a buffering strategy to try to retain unsent messages.

  • Buffering Unsent Messages: When the client calls connection.send() and the connection is unavailable (e.g., network interruption), the message is not immediately discarded but is buffered locally on the client.

  • Sending After Reconnection: Once the connection is restored, buffered messages are sent in their original order.

Server Behavior

The server does not provide a message buffering mechanism. Messages sent during a client disconnection are directly lost.

  • No Buffering of Messages: When the server sends messages using connection.send() or connection.broadcast(), if the target client is disconnected, the message is not stored.

  • No Resending: After a client reconnects, the server does not resend messages that were missed during the disconnection.

Strategies to Handle Message Loss

Due to the ​At-Most-Once Delivery​​ mechanism, you need to design additional reliability mechanisms based on business requirements. Below is a common strategy:

Application-Layer Acknowledgment Mechanism

  • Method: The sender includes a unique identifier (e.g., message ID) in the message, and the receiver responds with an acknowledgment message.

  • Implementation: If no acknowledgment is received, the sender can retry.

  • Use Case: Critical messages (e.g., document changes).

// Client sends a message with an ID
connection.send({ id: 'msg123', type: 'update', content: 'xxx' });

// Server acknowledges
server.on('message', ({ connection, data }) => {
    connection.send({ id: data.id, type: 'ack' });
});

// Client checks for acknowledgment
connection.on('message', (data) => {
    if (data.type === 'ack' && data.id === 'msg123') {
        console.log('Message delivered');
    }
});