# NDI Sender Listener

The `NDIlib_send_listener_create` function creates an instance of the sender listener. This function returns an instance of type `NDIlib_send_listener_instance_t` (or NULL if it fails), representing the sender listener instance. The parameters of the structure `NDIlib_send_listener_instance_t` are documented below.

<table><thead><tr><th valign="top">Parameter</th><th valign="top">Description</th></tr></thead><tbody><tr><td valign="top">p_url_address (const char*)</td><td valign="top"><p>This parameter represents the URL address of the NDI Discovery Server to connect to. If <code>NULL</code>, the default NDI discovery server will be used. If no discovery server is available, the sender listener will not be instantiated, and the create function will return <code>NULL</code>. The format of this field is expected to be the hostname or IP address, optionally followed by a colon and a port number. If the port number is not specified, port 5959 will be used.</p><p>For example: 127.0.0.1:5959, 127.0.0.1, or hostname:5959. If this field is a comma-separated list, only the first address will be used.</p></td></tr></tbody></table>

Once the structure is filled out, `NDIlib_send_listener_create` will create an instance for you. The sender listener instance can be destroyed by passing it into the `NDIlib_send_listener_destroy` function.

**Key Functions:**

### Check Listener Connection Status

To check if the sender listener is actively connected to the configured NDI Discovery server, call the following function:

`bool NDIlib_send_listener_is_connected(NDIlib_send_listener_instance_t p_instance);`

This function returns true if connected, otherwise false.

### Retrieve Server URL

To retrieve the URL address of the NDI Discovery server that the sender listener is connected to, call:

`const char* NDIlib_send_listener_get_server_url(NDIlib_recv_listener_instance_t p_instance);`

This function returns NULL if the sender instance pointer is invalid.

### Wait for Senders

To wait until the set of online senders has changed, call

`bool NDIlib_send_listener_wait_for_senders(NDIlib_send_listener_instance_t p_instance, uint32_t timeout_in_ms);`

This function takes a timeout in milliseconds. If a new sender is found or removed before the timeout elapses, the function returns true immediately. If no new senders are seen before the timeout, it returns false.

**Example Code:**

The following code will create an NDI sender listener instance and then retrieves the current list of advertised senders that are registered with the NDI Sender Advertiser API.

It uses the `NDIlib_send_listener_wait_for_senders` to sleep until new senders are found and, when they are seen, calls `NDIlib_send_listener_get_senders` to get the current list of senders:

```
// Create the descriptor of the object to create
NDIlib_send_listener_create_t sender_listener_create;
 
// The URL address of the discovery server to connect to
sender_listener_create.p_url_address = "127.0.0.1";
 
// Create an instance of the sender listener
NDIlib_send_listener_instance_t pNDI_send_listener = NDIlib_send_listener_create(&sender_listener_create);
if (!pNDI_send_listener) {
    return 0; // Handle error
}
 
// To remember the last connected state
bool last_connected = false;
 
while (true) { // You would not loop forever in a real application!
    // Check if the sender listener is currently connected
    bool curr_connected = NDIlib_send_listener_is_connected(pNDI_send_listener);
 
    // Has the connection state changed?
    if (last_connected != curr_connected) {
        printf("The listener is now %s.\n", curr_connected ? "connected" : "disconnected");
        last_connected = curr_connected;
    }
 
    // Wait up to 5 seconds to check for new senders
    if (!NDIlib_send_listener_wait_for_senders(pNDI_send_listener, 5000)) {
        // No new senders added
        printf("No change to the senders found.\n");
}
else
{
        // Get the updated list of senders
        uint32_t num_senders = 0;
        const NDIlib_sender_t* p_senders = NDIlib_send_listener_get_senders(pNDI_send_listener, &num_senders);
 
        // Display all of the found senders
        printf("Network senders (%u found).\n", num_senders);
        for (uint32_t i = 0; i != num_senders; i++) {
            printf("%u. %s\n", i + 1, p_senders[i].p_name);
        }
    }
}
 
// Destroy the sender listener
NDIlib_send_listener_destroy(pNDI_send_listener);
```

The call to `NDIlib_send_listener_get_senders` will give you a list of the advertised senders. The returned structure `NDIlib_sender_t` is only valid until the next call to `NDIlib_send_listener_get_senders` or until `NDIlib_send_listener_destroy` is called.

For a given `NDIlib_send_listener_instance_t`, do not call `NDIlib_send_listener_get_senders` asynchronously.

### Sender Information Structure

The structure for `NDIlib_sender_t` is documented below, which describes a sender that has been discovered.

<table><thead><tr><th valign="top">Parameters</th><th valign="top">Description</th></tr></thead><tbody><tr><td valign="top"><code>p_uuid</code> (const char*)</td><td valign="top">The unique identifier for the sender on the network.</td></tr><tr><td valign="top"><code>p_name</code> (const char*)</td><td valign="top">The human-readable name of the sender.</td></tr><tr><td valign="top"><code>p_metadata</code>(const char*)</td><td valign="top">Source metadata for the sender</td></tr><tr><td valign="top"><code>p_address</code> (const char*)</td><td valign="top">The known IP address of the sender.</td></tr><tr><td valign="top"><code>port</code> (int)</td><td valign="top">The port number of the sender</td></tr><tr><td valign="top"><p><code>p_groups</code> (const char**)</p><p> </p></td><td valign="top"><p>An array of strings, one for each group that the sender belongs to. The last entry in this list will be <code>NULL</code>.</p><p> </p></td></tr><tr><td valign="top"><code>num_groups</code> (uint32_t)</td><td valign="top">How many elements are in the <code>p_groups</code> array, excluding the <code>NULL</code> terminating entry.</td></tr><tr><td valign="top"><code>events_subscribed</code> (bool)</td><td valign="top">Indicates whether the sender is currently subscribed to receiving events.</td></tr></tbody></table>

We recommend reviewing the NDI SDK example code (`NDIlib_Send_Advertiser` and `NDIlib_Send_Listener`), which provides a simple illustration of how to implement these API’s.

{% hint style="info" %}
For monitoring sender events, access to the Advanced SDK APIs is required. Refer to the [Advanced SDK](https://docs.ndi.video/all/developing-with-ndi/advanced-sdk) section for more details.
{% endhint %}
