Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Dialers and Listeners

#define NNG_DIALER_INITIALIZER   // opaque value
#define NNG_LISTENER_INITIALIZER // opaque value

typedef struct nng_dialer_s nng_dialer;
typedef struct nng_listener_s nng_listener;

Dialers and listeners connect a socket to a transport address. A nng_dialer initiates outgoing connections to a remote listener. An nng_listener accepts incoming connections from remote dialers.

When a connection is established, NNG creates an nng_pipe and attaches it to the socket. A dialer creates at most one pipe at a time. A listener can create many pipes, which may be open concurrently.

NNG sometimes refers to dialers and listeners collectively as endpoints. That term is useful when discussing shared behavior, but the public API names are dialer and listener.

Note

The client/server relationship implied by dialer and listener is independent of protocol roles. For example, a REP socket can use a dialer to connect to a listener on a REQ socket. A socket can also have multiple dialers, multiple listeners, or both.

Initialization

nng_dialer d = NNG_DIALER_INITIALIZER;
nng_listener l = NNG_LISTENER_INITIALIZER;

The nng_dialer and nng_listener structures are opaque handles passed by value. They should be initialized with NNG_DIALER_INITIALIZER or NNG_LISTENER_INITIALIZER before they are opened, so that they cannot be confused with valid open handles.

Creating and Starting

int nng_dial(nng_socket s, const char *url, nng_dialer *dialerp, int flags);
int nng_dial_url(nng_socket s, const nng_url *url, nng_dialer *dialerp, int flags);

int nng_listen(nng_socket s, const char *url, nng_listener *listenerp, int flags);
int nng_listen_url(nng_socket s, const nng_url *url, nng_listener *listenerp, int flags);

The nng_dial and nng_dial_url functions create a dialer associated with socket s, configure it to connect to url, and start it. If dialerp is not NULL, the newly created dialer is stored there.

The nng_listen and nng_listen_url functions create a listener associated with socket s, configure it to listen at url, and start it. If listenerp is not NULL, the newly created listener is stored there.

The forms that take const char *url parse the URL from a string. The _url forms use an existing nng_url object.

Because these functions start the dialer or listener immediately, applications usually cannot apply additional transport options first. Use nng_dialer_create or nng_listener_create when configuration must be applied before starting.

Dialer Connection Behavior

Normally, the first dial attempt is made synchronously, including any required name resolution. If the connection is refused or otherwise fails, the error is returned immediately and no retry is scheduled.

If NNG_FLAG_NONBLOCK is supplied in flags, the first connection attempt is made asynchronously. In that mode, connection failures are retried in the background.

Once a dialer has connected successfully, it waits for the pipe to close. If the pipe closes, the dialer attempts to reconnect asynchronously, even if the original connection was made synchronously.

Tip

NNG_FLAG_NONBLOCK can make startup more resilient, but it can also make initial connection failures harder to diagnose. Use nng_dialer_start_aio when the application needs asynchronous startup and the result of the first dial attempt.

Listener Behavior

The flags argument to nng_listen and nng_listen_url is ignored and reserved for future use.

A listener continues to accept new connections, associating their pipes with the socket, until either the listener or the socket is closed.

Errors

The create-and-start functions can return:

Creating Before Starting

int nng_dialer_create(nng_dialer *dialerp, nng_socket s, const char *url);
int nng_dialer_create_url(nng_dialer *dialerp, nng_socket s, const nng_url *url);

int nng_listener_create(nng_listener *listenerp, nng_socket s, const char *url);
int nng_listener_create_url(nng_listener *listenerp, nng_socket s, const nng_url *url);

The nng_dialer_create and nng_dialer_create_url functions create a dialer associated with socket s, configure it to connect to url, and store it in dialerp. The dialer is not started.

The nng_listener_create and nng_listener_create_url functions create a listener associated with socket s, configure it to listen at url, and store it in listenerp. The listener is not started.

Use these functions when the dialer or listener needs additional configuration before it starts, such as transport options, TLS configuration, or a listener socket activation file descriptor.

Errors

These functions can return:

Starting

int nng_dialer_start(nng_dialer dialer, int flags);
void nng_dialer_start_aio(nng_dialer dialer, int flags, nng_aio *aio);
int nng_listener_start(nng_listener listener, int flags);

The nng_dialer_start function starts dialer. It follows the same synchronous and NNG_FLAG_NONBLOCK behavior described for nng_dial.

The nng_dialer_start_aio function starts dialer asynchronously using aio. It must be called with NNG_FLAG_NONBLOCK in flags. When the first dial attempt completes, the operation result is reported through aio. Only the first dialing result is reported this way.

The nng_listener_start function starts listener, causing it to bind to its address and accept connections. The flags argument is ignored and reserved for future use.

Once a dialer or listener has started, it is generally not possible to change its configuration.

Errors

nng_dialer_start can return, and nng_dialer_start_aio can report through its AIO, these errors:

nng_listener_start can fail with:

Closing

int nng_dialer_close(nng_dialer dialer);
int nng_listener_close(nng_listener listener);

The nng_dialer_close function closes dialer. The nng_listener_close function closes listener.

Closing a dialer or listener also closes any pipes it created. Once this function returns, the dialer or listener and its resources are deallocated. Further attempts to use the handle will fail with NNG_ECLOSED.

Dialers and listeners are also closed when their associated socket is closed.

Errors

These functions can return:

  • NNG_ECLOSED: The handle does not refer to an open dialer or listener.

Identity

int nng_dialer_id(nng_dialer dialer);
int nng_listener_id(nng_listener listener);

The nng_dialer_id and nng_listener_id functions return a positive identifier if the supplied handle is valid. Otherwise they return -1.

A dialer or listener is considered valid if it was ever created by one of the create or create-and-start functions. Handles allocated on the stack or statically should be initialized with NNG_DIALER_INITIALIZER or NNG_LISTENER_INITIALIZER before use.

Associated URLs

int nng_dialer_get_url(nng_dialer dialer, const nng_url **urlp);
int nng_listener_get_url(nng_listener listener, const nng_url **urlp);

The nng_dialer_get_url and nng_listener_get_url functions return the URL associated with dialer or listener. The URL pointer is stored in urlp.

The returned URL belongs to the dialer or listener. It must not be modified or freed by the caller, and it is invalid after the dialer or listener is closed.

Note

Older NNG documentation referred to an NNG_OPT_URL option for endpoints. That option has been removed. Use nng_dialer_get_url and nng_listener_get_url instead, which return a typed nng_url object rather than a string.

Errors

These functions can return:

  • NNG_ECLOSED: The handle does not refer to an open dialer or listener.

Options

int nng_dialer_get_bool(nng_dialer dialer, const char *opt, bool *valp);
int nng_dialer_get_int(nng_dialer dialer, const char *opt, int *valp);
int nng_dialer_get_ms(nng_dialer dialer, const char *opt, nng_duration *valp);
int nng_dialer_get_size(nng_dialer dialer, const char *opt, size_t *valp);
int nng_dialer_get_addr(nng_dialer dialer, const char *opt, nng_sockaddr *valp);
int nng_dialer_get_string(nng_dialer dialer, const char *opt, const char **valp);
int nng_dialer_get_uint64(nng_dialer dialer, const char *opt, uint64_t *valp);

int nng_listener_get_bool(nng_listener listener, const char *opt, bool *valp);
int nng_listener_get_int(nng_listener listener, const char *opt, int *valp);
int nng_listener_get_ms(nng_listener listener, const char *opt, nng_duration *valp);
int nng_listener_get_size(nng_listener listener, const char *opt, size_t *valp);
int nng_listener_get_string(nng_listener listener, const char *opt, const char **valp);
int nng_listener_get_uint64(nng_listener listener, const char *opt, uint64_t *valp);

int nng_dialer_set_bool(nng_dialer dialer, const char *opt, bool val);
int nng_dialer_set_int(nng_dialer dialer, const char *opt, int val);
int nng_dialer_set_ms(nng_dialer dialer, const char *opt, nng_duration val);
int nng_dialer_set_size(nng_dialer dialer, const char *opt, size_t val);
int nng_dialer_set_addr(nng_dialer dialer, const char *opt, const nng_sockaddr *val);
int nng_dialer_set_string(nng_dialer dialer, const char *opt, const char *val);
int nng_dialer_set_uint64(nng_dialer dialer, const char *opt, uint64_t val);

int nng_listener_set_bool(nng_listener listener, const char *opt, bool val);
int nng_listener_set_int(nng_listener listener, const char *opt, int val);
int nng_listener_set_ms(nng_listener listener, const char *opt, nng_duration val);
int nng_listener_set_size(nng_listener listener, const char *opt, size_t val);
int nng_listener_set_string(nng_listener listener, const char *opt, const char *val);
int nng_listener_set_uint64(nng_listener listener, const char *opt, uint64_t val);

The nng_dialer_get and nng_listener_get function families retrieve option values from a dialer or listener. The nng_dialer_set and nng_listener_set function families configure option values on a dialer or listener.

The function suffix identifies the type used for the option:

SuffixTypeUse
_boolboolBoolean options.
_intintInteger options.
_msnng_durationTime durations, stored as milliseconds.
_sizesize_tBuffer sizes, maximum message sizes, and similar values.
_addrnng_sockaddrSocket addresses. This form is available for dialer options only.
_stringconst char *NUL-terminated UTF-8 or ASCII strings.
_uint64uint64_t64-bit unsigned values, typically identifiers, network numbers, and similar values.

Available options vary by transport and by option. Many common options are listed in Socket Options and transport-specific options are documented with each transport.

Endpoint-Specific Options

The following endpoint-specific option is defined by the core API:

OptionTypeDescription
NNG_OPT_LOCADDRnng_sockaddrDialers only. Configures the local address to bind before initiating outgoing connections, when supported by the transport.

NNG_OPT_LOCADDR is most useful for transports such as TCP or UDP where the application needs to choose the local interface or source address for outgoing connections. When used on a TCP dialer, the IP address portion is used as the source address, but the port is ignored and an ephemeral port is chosen by the system.

Note

Support for NNG_OPT_LOCADDR depends on the transport. Some transports support it on dialers, some do not, and listeners may expose related local-address information differently or not at all.

Note

Socket option values for NNG_OPT_RECONNMAXT, NNG_OPT_RECONNMINT, and NNG_OPT_RECVMAXSZ provide initial defaults for dialers and listeners created afterward. Changing those socket options does not affect existing dialers or listeners.

Note

Once a dialer or listener has started, it is generally not possible to change its configuration.

Errors

The option functions can return:

TLS Configuration

int nng_dialer_get_tls(nng_dialer dialer, nng_tls_config **cfgp);
int nng_dialer_set_tls(nng_dialer dialer, nng_tls_config *cfg);
int nng_listener_get_tls(nng_listener listener, nng_tls_config **cfgp);
int nng_listener_set_tls(nng_listener listener, nng_tls_config *cfg);

These functions configure or retrieve TLS configuration objects for dialers and listeners whose transports support TLS. They are documented in Using Configuration Objects.

Windows Security Descriptors

int nng_listener_set_security_descriptor(nng_listener listener, void *desc);

The nng_listener_set_security_descriptor function configures the Windows security descriptor for listener. This is used by transports that expose Windows named objects, such as the IPC transport. It must be called before the listener is started.

Errors

This function can return:

Examples

Connecting With Convenience Functions

nng_socket s;
nng_dialer d = NNG_DIALER_INITIALIZER;

nng_req0_open(&s);
nng_dial(s, "tcp://127.0.0.1:8080", &d, 0);

Configuring Before Starting

nng_socket s;
nng_listener l = NNG_LISTENER_INITIALIZER;

nng_rep0_open(&s);
nng_listener_create(&l, s, "tcp://127.0.0.1:8080");
nng_listener_set_size(l, NNG_OPT_RECVMAXSZ, 1024 * 1024);
nng_listener_start(l, 0);