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

> 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

Use the `RtmClient` instance to subscribe to Signaling events:

```csharp
// Add a message event listener
rtmClient.OnMessageEvent += newMessageEvent =>
{
    var channelName = newMessageEvent.channelName;
    var channelType = newMessageEvent.channelType;
    var topic = newMessageEvent.channelTopic;
    var publisher = newMessageEvent.publisher;
    var messageType = newMessageEvent.messageType;
    var message = newMessageEvent.message;
    var customType = newMessageEvent.customType;
    // your Logic
};

// Add a presence event listener
rtmClient.OnPresenceEvent += newPresenceEvent =>
{
    var channelName = newPresenceEvent.channelName;
    var channelType = newPresenceEvent.channelType;
    var eventType = newPresenceEvent.type;
    var publisher = newPresenceEvent.publisher;
    var stateItems = newPresenceEvent.stateItems;
    var interval = newPresenceEvent.interval;
    var snapshot = newPresenceEvent.snapshot;
    // your Logic
};

// Add a topic event listener
rtmClient.OnTopicEvent += newTopicEvent =>
{
    var channelName = newTopicEvent.channelName;
    var eventType = newTopicEvent.type;
    var publisher = newTopicEvent.publisher;
    var topicInfos = newTopicEvent.topicInfos;
    if (topicInfos != null)
    {
        // your logic
    }
};

// Add a storage event listener
rtmClient.OnStorageEvent += newStorageEvent =>
{
    var channelName = newStorageEvent.channelName;
    var channelType = newStorageEvent.channelType;
    var eventType = newStorageEvent.eventType;
    var category = newStorageEvent.target;
    var data = newStorageEvent.data;
    if (data != null)
    {
        // your logic
    }
};

// Add a lock event listener
rtmClient.OnLockEvent += newLockEvent =>
{
    var channelName = newLockEvent.channelName;
    var channelType = newLockEvent.channelType;
    var eventType = newLockEvent.eventType;
    var LockDetail = newLockEvent.lockDetailList;
    if( LockDetail != null )
    {
        // your logic
    }
};

// Add a OnConnectionStateChange event listener
rtmClient.OnConnectionStateChanged +=(channelName, state, reason ) =>
{
    Debug.Log(string.Format("OnConnectionStateChanged channelName {0}: state:{1} reason:{2}", channelName, state, reason);
    // your logic
};

// Add a OnTokenPrivilegeWillExpire event listener
rtmClient.OnTokenPrivilegeWillExpire += channelName =>
{
    Debug.Log(string.Format("OnTokenPrivilegeWillExpire channelName {0}", channelName));
    // your logic
};
```

### Remove event listeners

To avoid performance degradation caused by memory leaks, errors, and null pointer exceptions, best practice is to unsubscribe from events when you no longer need to use them.

```csharp
private void AddEventsListener()
{
    rtmClient.OnMessageEvent += OnMessageEvent;
    rtmClient.OnPresenceEvent += OnPresenceEvent;
    rtmClient.OnTopicEvent += OnTopicEvent;
    rtmClient.OnStorageEvent += OnStorageEvent;
    rtmClient.OnLockEvent += OnLockEvent;
    rtmClient.OnConnectionStateChanged += OnConnectionStateChanged;
    rtmClient.OnTokenPrivilegeWillExpire += OnTokenPrivilegeWillExpire;
}

private void RemoveEventsListener()
{
    rtmClient.OnMessageEvent -= OnMessageEvent;
    rtmClient.OnPresenceEvent -= OnPresenceEvent;
    rtmClient.OnTopicEvent -= OnTopicEvent;
    rtmClient.OnStorageEvent -= OnStorageEvent;
    rtmClient.OnLockEvent -= OnLockEvent;
    rtmClient.OnConnectionStateChanged -= OnConnectionStateChanged;
    rtmClient.OnTokenPrivilegeWillExpire -= OnTokenPrivilegeWillExpire;
}

private void OnMessageEvent( MessageEvent Event) { }

private void OnPresenceEvent( PresenceEvent Event) { }

private void OnTopicEvent( TopicEvent Event) { }
```

The `RtmClient` automatically destroys event handlers when you call `Dispose`.

### Signaling events

Signaling SDK offers the following callbacks:

| Event Listener               | Description                                                                                                                                                                                                                                                                                                  |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `OnMessageEvent`             | 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. The event payload data includes channel name, channel type, topic name, event sender, message payload, and data type.         |
| `OnPresenceEvent`            | 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, and user temporary status data.                                    |
| `OnTopicEvent`               | Receive notifications of topic change events in the message channels you have subscribed to and stream channels you have joined. The event payload data includes information such as channel name, event type, topic name, and event sender.                                                                 |
| `OnStorageEvent`             | 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. The event payload data includes information such as channel name, channel type, and event type. |
| `OnLockEvent`                | 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.                                                                       |
| `OnConnectionStateChanged`   | Receive event notifications for client network connection status changes, including channel name, connection status, reason for change, and other information.                                                                                                                                               |
| `OnTokenPrivilegeWillExpire` | Receive event 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.

    
  
