= nng_compat(3compat)
//
// Copyright 2018 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
//
// This document is supplied under the terms of the MIT License, a
// copy of which should be located in the distribution where this
// file was obtained (LICENSE.txt).  A copy of the license may also be
// found online at https://opensource.org/licenses/MIT.
//

== NAME

nng_compat - compatibility with nanomsg 1.0

== SYNOPSIS

[source, c]
----
#include <nanomsg/nn.h>

#include <nanomsg/bus.h>
#include <nanomsg/pair.h>
#include <nanomsg/pipeline.h>
#include <nanomsg/pubsub.h>
#include <nanomsg/reqrep.h>
#include <nanomsg/survey.h>

#include <nanomsg/inproc.h>
#include <nanomsg/ipc.h>
#include <nanomsg/tcp.h>
#include <nanomsg/ws.h>
----

== DESCRIPTION

(((compatibility layer)))
The <<nng.7#,_nng_>> library provides source-level compatibility for
most _nanomsg_ 1.0 applications.

IMPORTANT: This is intended to facilitate converting ((legacy applications)) to
use the _nng_ library.
New applications should use the newer <<nng.7#,_nng_>> API instead.

Applications making use of this must take care
to link with <<libnng.3#,_libnng_>> instead of _libnn_.

TIP: While not recommended for long term use, the value returned by
<<nng_socket_id.3#,nng_socket_id()>> can be used with these functions
just like a value returned by <<nn_socket.3compat#,nn_socket()>>.
This can be way to facilitate incremental transition to the new API.

NOTE: Some capabilities, protocols, and transports, will not be accessible
using this API, as the compatible API has no provision for expression
of certain concepts introduced in the newer <<nng.7#,_nng_>> API.

NOTE: While reasonable efforts have been made to provide for compatibility,
some things may behave differently, and some less common parts of the
_nanomsg_ 1.0 API are not supported at this time, including certain
options and the statistics API.
See the <<Caveats>> section below.

=== Compiling

When compiling legacy _nanomsg_ applications, it will generally be
necessary to change the include search path to add the "`compat`" subdirectory
of the directory where headers were installed.
For example, if _nng_ is installed in `$prefix`, then header files will
normally be located in `$prefix/include/nng`.
In this case, to build legacy _nanomsg_ apps against _nng_ you would
add `$prefix/include/nng/compat` to your compiler's search path.

Alternatively, you can change your source code so that `#include` statements
referring to `<nanomsg>` instead refer to `<nng/compat/nanomsg>`.
For example, instead of:

[source,c]
----
#include <nanomsg/nn.h>
#include <nanomsg/reqrep.h>
----

you would have this:

[source,c]
----
#include <nng/compat/nanomsg/nn.h>
#include <nng/compat/nanomsg/reqrep.h>
----

Legacy applications built using these methods should be linked against _libnng_
instead of _libnn_, just like any other _nng_ application.

=== Functions

The following functions are provided:

// For PDF, we don't have horizontal lists, so we have to conditionalize
// this and use tables there -- it looks ugly otherwise.
ifndef::backend-pdf[]
[horizontal]
`<<nn_socket.3compat#,nn_socket()>>`:: create socket
`<<nn_getsockopt.3compat#,nn_getsockopt()>>`:: get socket option
`<<nn_setsockopt.3compat#,nn_setsockopt()>>`:: set socket option
`<<nn_bind.3compat#,nn_bind()>>`:: accept connections from remote peers
`<<nn_connect.3compat#,nn_connect()>>`:: connect to remote peer
`<<nn_send.3compat#,nn_send()>>`:: send data
`<<nn_recv.3compat#,nn_recv()>>`:: receive data
`<<nn_shutdown.3compat#,nn_shutdown()>>`:: shut down endpoint
`<<nn_close.3compat#,nn_close()>>`:: close socket
`<<nn_poll.3compat#,nn_poll()>>`:: poll sockets
`<<nn_device.3compat#,nn_device()>>`:: create forwarding device
`<<nn_recvmsg.3compat#,nn_recvmsg()>>`:: receive message
`<<nn_sendmsg.3compat#,nn_sendmsg()>>`:: send message
`<<nn_cmsg.3compat#,nn_cmsg()>>`:: message control data
`<<nn_get_statistic.3compat#,nn_get_statistic()>>`:: get statistic (stub)
`<<nn_allocmsg.3compat#,nn_allocmsg()>>`:: allocate message
`<<nn_reallocmsg.3compat#,nn_reallocmsg()>>`:: reallocate message
`<<nn_freemsg.3compat#,nn_freemsg()>>`:: free message
`<<nn_errno.3compat#,nn_errno()>>`:: return most recent error
`<<nn_strerror.3compat#,nn_strerror()>>`:: return message for error
`<<nn_term.3compat#,nn_term()>>`:: terminate library
endif::[]
ifdef::backend-pdf[]
// Add links for the following as they are written.
[.hdlist,width=90%, grid=rows,cols="1,2", align="center"]
|===
|`<<nn_socket.3compat#,nn_socket()>>`|create socket
|`<<nn_getsockopt.3compat#,nn_getsockopt()>>`|get socket option
|`<<nn_setsockopt.3compat#,nn_setsockopt()>>`|set socket option
|`<<nn_bind.3compat#,nn_bind()>>`|accept connections from remote peers
|`<<nn_connect.3compat#,nn_connect()>>`|connect to remote peer
|`<<nn_send.3compat#,nn_send()>>`|send data
|`<<nn_recv.3compat#,nn_recv()>>`|receive data
|`<<nn_shutdown.3compat#,nn_shutdown()>>`|shut down endpoint
|`<<nn_close.3compat#,nn_close()>>`|close socket
|`<<nn_poll.3compat#,nn_poll()>>`|poll sockets
|`<<nn_device.3compat#,nn_device()>>`|create forwarding device
|`<<nn_recvmsg.3compat#,nn_recvmsg()>>`|receive message
|`<<nn_sendmsg.3compat#,nn_sendmsg()>>`|send message
|`<<nn_cmsg.3compat#,nn_cmsg()>>`|message control data
|`<<nn_get_statistic.3compat#,nn_get_statistic()>>`|get statistic (stub)
|`<<nn_allocmsg.3compat#,nn_allocmsg()>>`|allocate message
|`<<nn_reallocmsg.3compat#,nn_reallocmsg()>>`|reallocate message
|`<<nn_freemsg.3compat#,nn_freemsg()>>`|free message
|`<<nn_errno.3compat#,nn_errno()>>`|return most recent error
|`<<nn_strerror.3compat#,nn_strerror()>>`|return message for error
|`<<nn_term.3compat#,nn_term()>>`|terminate library
|===
endif::[]

=== Caveats

The following caveats apply when using the legacy API with _nng_.

* Socket numbers can be quite large.
  The legacy _libnanomsg_ attempted to reuse socket numbers, like
  file descriptors in UNIX systems.
  The _nng_ library avoids this to prevent accidental reuse or
  collision after a descriptor is closed.
  Consequently, socket numbers can become quite large, and should
  probably not be used for array indices.

* The following options (`nn_getsockopt`) are unsupported:
  `NN_SNDPRIO`, `NN_RCVPRIO`, `NN_IPV4ONLY`.
  The priority options may be supported in the future, when
  the underlying capability is present in _nng_.

* Access to statistics using this legacy API
  (`<<nn_get_statistic.3compat#,nn_get_statistic()>>`) is unsupported.

* Some transports can support longer URLs than legacy _libnanomsg_ can.
  It is a good idea to use short pathnames in URLs if interoperability
  is a concern.

* Only absolute paths are supported in `ipc://` URLs.
  For example, `ipc:///tmp/mysocket` is acceptable, but `ipc://mysocket` is not.

* The WebSocket transport in this implementation (`ws://` URLs)
  only supports BINARY frames.

* Some newer transports are unusable from this mode.
  In particular, this legacy API offers no way to configure
  TLS or ZeroTier parameters that may be required for use.

* ABI versioning of the compatibility layer is not supported,
  and the `NN_VERSION_` macros are not present.

* Runtime symbol information is not implemented.
  Specifically, there is no `nn_symbol()` function yet.
  (This may be addressed later if there is a need.)

* The TCP transport (`tcp://` URLs) does not support specifying the local
  address or interface when binding.  (This could be fixed in the future,
  but most likely this will be available only using the new API.)

* The values of `NN_RCVMAXSIZE` are constrained.
  Specifically, values set larger than 2GB using the new API will be reported
  as unlimited (`-1`) in the new API, and the value `0` will disable any
  enforcement, just like `-1`.
  (There is no practical reason to ever want to limit the receive size to
  zero.)

* This implementation counts buffers in terms of messages rather than bytes.
  As a result, the buffer sizes accessed with `NN_SNDBUF` and `NN_RCVBUF` are
  rounded up to a whole number of kilobytes, then divided by 1024, in order
  to approximate buffering assuming 1 KB messages.
  Few applications should need to adjust the default values.

== SEE ALSO

[.text-left]
<<libnng.3#,libnng(3)>>,
<<nng.7#,nng(7)>>
