NNG (nanomsg-next-gen)

repository·main·Indexed 26 days ago

https://github.com/nanomsg/nng

A lightweight, broker-less messaging library written in C. NNG provides high-performance, scalable, and secure asynchronous messaging patterns such as pub/sub and request/reply. It is designed as a next-generation rewrite of nanomsg, offering wire and API compatibility with nanomsg and mangos. Key features include support for TLS 1.2 and 1.3, an asynchronous I/O framework with thread pools, and a simple API for managing common messaging patterns without manual connection or retry handling.

Tokens
55.3K
Snippets
128
Records
324
Agent score
88%

What's inside NNG

  1. Overview of NNG messaging capabilities

    main

    NNG is a lightweight, broker-less messaging library implemented in C. It provides a simple API to handle common messaging patterns without requiring the developer to manage connection details, retries, or plumbing.

    Key features include:

    • Scalability: Uses an asynchronous I/O framework and thread pools to utilize multiple cores.
    • Security: Supports TLS (1.2 and optionally 1.3) for authentication and encryption.
    • Patterns: Supports common patterns like publish/subscribe, RPC-style request/reply, and service discovery.
    • Compatibility: Offers both wire and API compatibility with nanomsg and mangos, allowing existing applications to inter-operate with NNG.
  2. Manage concurrency using Contexts

    main

    Contexts in NNG provide isolation for protocol-specific state machines and associated data. This allows multiple concurrent transactions to coexist on a single socket. This is particularly useful for protocols like REP, REQ, RESPONDENT, SURVEYOR, and SUB to handle multiple requests concurrently without blocking the entire socket.

    Note: Contexts cannot be used with file descriptor polling via nng_socket_get_recv_poll_fd or nng_socket_get_send_poll_fd.

  3. Manage Asynchronous I/O with nng_aio

    main

    NNG uses the nng_aio opaque structure to perform asynchronous operations. Each nng_aio handle can only be used for a single operation at a time. When an operation is initiated, the application registers a callback function that is executed exactly once upon completion (success or failure).

    Key Concepts:

    • Callbacks: Executed when the operation completes. Note that callbacks may be executed on a different thread, so use synchronization to avoid data races.
    • Scalability: Using asynchronous operations is preferred over manual threading for high-performance, low-latency applications to minimize resource overhead.
  4. Use the ID Map supplemental feature

    main

    The nng_id_map provides a table that maps 64-bit unsigned integer identifiers to user-supplied pointers. It is a supplemental feature used for efficient sparse mapping of IDs to data.

    Important Requirements:

    • You must include #include <nng/supplemental/util/idhash.h> in your project.
    • The functions are not thread-safe. You must use a mutex or similar synchronization mechanism if accessing the map from multiple threads.
    • Values (pointers) stored in the map must not be NULL.
    • The map can store at most $2^{32}$ identifiers, even though the identifiers themselves can be larger 64-bit values.
  5. Understand the NNG Conceptual Model

    main

    NNG is built on two core pillars: Protocols and Transports.

    • Protocols: Define messaging semantics and patterns (e.g., request/reply, publish/subscribe, pipelines, surveys, and buses). Each socket implements exactly one protocol.
    • Transports: Define the underlying communication mechanism (e.g., TCP, IPC, TLS, WebSocket, or in-process channels).

    Key Abstractions

    • Sockets: The primary interface for applications. Sockets are message-oriented; messages are delivered whole or not at all. Sockets use protocol-specific constructors.
    • Endpoints (Dialers and Listeners): Sockets communicate via endpoints. Dialers initiate outbound connections to a URL, while Listeners accept inbound connections at a URL.
    • Pipes: The message-oriented connections between peers created by endpoints. For stream-oriented transports like TCP or IPC, a pipe typically corresponds to a single OS socket.
    • Raw Mode: While most applications use "cooked" sockets that handle protocol semantics automatically, applications like proxies or devices can use raw mode sockets to take direct responsibility for protocol headers and processing.
  6. Use the SUB protocol for subscriber patterns

    main

    The SUB protocol is the subscriber side of a publisher/subscriber pattern. In this pattern, a publisher broadcasts data to all subscribers, but subscribers only receive messages that match their specific subscription topics.

    Important Implementation Details:

    • Filtering: Subscriptions are matched against the leading bytes of the message body. To match a subscription, a message must have at least sz bytes, and the first sz bytes must match the subscription buffer buf.
    • Bandwidth: This pattern should not be used to reduce bandwidth consumption, as the publisher delivers all messages to all subscribers; filtering happens locally on the subscriber side.
    • Receive All: To receive all messages without filtering, subscribe to a zero-length topic.
  7. Use the REQ protocol for request/reply patterns

    main

    The REQ protocol is the requester side of a request/reply pattern. It is used to send a message to a single replier and wait for a response. This protocol is ideal for RPC-like services because it is 'reliable': the requester will automatically resend the request if no reply arrives, until a reply is received or the request times out.

    Important Considerations:

    • Idempotency: Because requests are automatically resent, ensure your requests are idempotent to prevent side effects from duplicate requests (e.g., if a reply was lost but the request was processed).
    • Load Balancing: The requester generally has only one outstanding request at a time and will attempt to spread work requests across different peer repliers.
    • Raw Mode: Using [raw mode] bypasses the standard state machine and operational restrictions.
  8. Use the PUB protocol for publisher/subscriber patterns

    main

    The PUB protocol is used to implement the publisher side of a publisher/subscriber pattern. In this pattern, a publisher broadcasts data to all connected subscribers.

    Important Implementation Details:

    • Filtering: Subscribers maintain their own subscriptions and filter messages locally. This means the publisher delivers all messages to all subscribers regardless of topic. Do not use this pattern to reduce bandwidth consumption.
    • Topic Structure: The topic is defined as the first part of the message body. Applications must construct their messages such that the topic is the prefix.
  9. Access the NNG Reference Manual

    main
    The primary technical documentation and API reference for NNG is provided in mdbook format. You can access the documentation online or view the source files in the ref/ subdirectory of the repository.
  10. Use the REP protocol for request/reply services

    main
    The REP protocol is the replier side of the request/reply pattern. It is designed for setting up RPC-like services. In this pattern, a requester sends a message to a replier, and the replier is expected to respond. The protocol is reliable because the requester will retry sending the request until a reply is received or a timeout occurs.
  11. Available Scalability Protocols in NNG

    main

    NNG includes several Scalability Protocols representing common networking patterns:

    • Request - Reply: Uses REQ and REP protocols for RPC-like services.
    • Pipeline: Uses PUSH and PULL protocols for distribution and flow control.
    • Publish - Subscribe
    • Bus
    • Pair
  12. Available NNG Transports

    main

    NNG supports several transport layers for its Scalability Protocols, allowing for communication across different boundaries (intra-process, inter-process, or over networks). The available transports are:

    • Intra-Process (inproc): For communication between threads within the same process.
    • Inter-Process (ipc): For communication between different processes on the same host.
    • TCP (tcp): Standard TCP/IP networking.
    • TLS (tls): Secure TCP communication using Transport Layer Security.
    • DTLS (dtls): Secure datagram communication using Datagram Transport Layer Security.
    • WebSocket (ws): Communication over WebSockets.
    • BSD Socket (socket): Direct access to BSD sockets.
    • UDP (udp): Datagram communication over UDP.