# Event listeners (/en/realtime-media/rtm/build/send-and-receive-messages/add-event-listener/web)

> For AI agents: see the complete documentation index at [llms.txt](/llms.txt).

To receive message and event notifications when you subscribe to or join channels, you add an event listener. An event listener is triggered by the SDK to inform the client about Signaling events and state changes. The listener enables you to respond to events like successful connection to Signaling, token expiration, received messages, and other presence, storage, and lock events.

## Prerequisites

Ensure that you have integrated the Signaling SDK in your project and implemented the framework functionality from the [SDK quickstart](../../index) page.

## Implement event listeners

This section shows how to use the Signaling SDK to implement event listeners.

### Add event listeners

To incorporate event handling into your app, use the `addEventListener` method. This method allows you to add event bindings by configuring a callback
function tailored to your specific requirements:

```java
// Handle message event
rtm.addEventListener("message", event => {
    const channelType = event.channelType;      // The channel type, 'STREAM' 'MESSAGE', or 'USER'
    const channelName = event.channelName;      // The name of the channel that this message came from
    const topic = event.topicName;              // (Stream channel only) The name of the topic that this message came from
    const messageType = event.messageType;      // The message type, 'STRING' or 'BINARY'
    const customType = event.customType;        // User defined type
    const publisher = event.publisher;          // The message publisher
    const message = event.message;              // The message payload
    const timestamp = event.timestamp;          // Event timestamp
});
// Handle presence event
rtm.addEventListener("presence", event => {
    const action = event.eventType;             // The event type, should be one of 'SNAPSHOT', 'INTERVAL', 'JOIN', 'LEAVE', 'TIMEOUT、'STATE_CHANGED', 'OUT_OF_SERVICE'.
    const channelType = event.channelType;      // The channel type, should be "STREAM", "MESSAGE" or "USER"
    const channelName = event.channelName;      // The name of the channel this event came from
    const publisher = event.publisher;          // The user who triggered this event
    const states = event.stateChanged;          // User state payload, only for the stateChanged event
    const interval = event.interval;            // Interval payload, only for the interval event
    const snapshot = event.snapshot;            // Snapshot payload, only for the snapshot event
    const timestamp = event.timestamp;          // Event timestamp
});
// Handle topic event
rtm.addEventListener("topic", event => {
    const action = event.evenType;              // The event type, should be one of 'SNAPSHOT', 'JOIN', 'LEAVE'.
    const channelName = event.channelName;      // The name of the channel this event came from
    const publisher = event.userId;             // The user who triggered this event
    const topicInfos = event.topicInfos;        // Topic information payload
    const totalTopics = event.totalTopics;      // The number of topics
    const timestamp = event.timestamp;          // Event timestamp
});
// Handle storage event
rtm.addEventListener("storage", event => {
    const channelType = event.channelType;      // The channel type, should be "STREAM", "MESSAGE" or "USER"
    const channelName = event.channelName;      // The name of the channel this event came from
    const publisher = event.publisher;          // The user who triggered this event
    const storageType = event.storageType;      // The storage type, should be 'USER' or 'CHANNEL'
    const action = event.eventType;             // The event type, should be one of 'SNAPSHOT', 'SET', 'REMOVE', 'UPDATE', or 'NONE'
    const data = event.data;                    // 'USER_METADATA' or 'CHANNEL_METADATA' payload
    const timestamp = event.timestamp;          // Event timestamp
});
// Handle lock event
rtm.addEventListener("lock", event => {
    const channelType = event.channelType;      // The channel type, should be "STREAM", "MESSAGE" or "USER"
    const channelName = event.channelName;      // The name of the channel this event came from
    const publisher = event.publisher;          // The user who triggered this event
    const action = event.evenType;              // The event type, should be one of 'SET', 'REMOVED', 'ACQUIRED', 'RELEASED', 'EXPIRED', 'SNAPSHOT'
    const lockName = event.lockName;            // The name of the lock it affects
    const ttl = event.ttl;                      // The ttl of this lock
    const snapshot = event.snapshot;            // Snapshot payload
    const owner = event.owner;                  // The owner of this lock
    const timestamp = event.timestamp;          // Event timestamp
});
// Handle connection state change event
rtm.addEventListener("status", event => {
    const currentState = event.state;           // Current connection state
    const changeReason = event.reason;          // Why the event was triggered
    const timestamp = event.timestamp;          // Event timestamp
});
// Handle link state change event
rtm.addEventListener('linkState', event => {
    const currentState = event.currentState;
    const previousState = event.previousState;
    const serviceType = event.serviceType;
    const operation = event.operation;
    const reason = event.reason;
    const affectedChannels = event.affectedChannels;
    const timestamp = event.timestamp;
    const isResumed = event.isResumed;
});
// Handle token privilege will expire event
rtm.addEventListener("tokenPrivilegeWillExpire", (channelName) => {
    const channelName = channelName;            // The channel for which the token will expire
});
```

### Remove event listeners

To avoid performance degradation caused by memory leaks, errors, and null pointer exceptions, best practice is to unregister the event handler when you no longer need to use it.

```javascript
const messageReceived = (event) => {
    const channelType = event.channelType;      // The channel type, should be 'STREAM' or 'MESSAGE'
    const channelName = event.channelName;      // The name of the channel this event came from
    const topic = event.topicName;              // The message topic, valid when the channelType is "STREAM".
    const messageType = event.messageType;      // The message type, should be "STRING" or "BINARY" .
    const customType = event.customType;        // User defined type
    const publisher = event.publisher;          // Message publisher
    const message = event.message;              // Message payload
    const timestamp = event.timestamp;          // Event timestamp
    // Your business processing logic program
};

// Add Event Listener
rtm.addEventListener("message", messageReceived);

// Remove Event Listener
rtm.removeEventListener("message", messageReceived);
```

### Signaling events

Signaling offers the following events:

| Event Listener             | Description                                                                                                                                                                                                                                                                                  |
| -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `message`                  | Receive message notifications from all the message channels you have subscribed to, or topic message notifications subscribed to from all the stream channels you have joined.                                                                                                               |
| `presence`                 | Receive online status event notifications from remote users in all the message channels you have subscribed to and stream channels you have joined. The event payload data includes channel name, channel type, event type, event sender, user temporary status data, and other information. |
| `topic`                    | Receive notifications of topic change events in all the stream channels you have joined. The event payload data includes information such as channel name, event type, topic name, and event sender.                                                                                         |
| `storage`                  | Receive all channel metadata event notifications in the message channels you have subscribed to and stream channels you have joined, as well as user metadata event notifications from all subscribed users.                                                                                 |
| `lock`                     | Receive all lock event notifications in the message channels you have subscribed to and stream channels you have joined. The event payload data contains information such as channel name, channel type, event type, and lock details.                                                       |
| `status`                   | Receive event notifications for client network connection status changes. This includes channel name, connection status, reason for change, and other information.                                                                                                                           |
| `linkState`                | Receive notifications about changes in the client's network connection status, including information on the state before and after the change, service type, operation type, reason for the change, and channel list.                                                                        |
| `tokenPrivilegeWillExpire` | Receive notifications when the client token is about to expire.                                                                                                                                                                                                                              |

For details on the parameters passed in by each event, refer to [Event listeners](/en/api-reference/api-ref/signaling#event-listeners) in the API reference.

    
  
      
  
      
  
      
  
      
  
      
  
      
  
      
  
      
  
