Interface Connection

  • All Superinterfaces:
    java.lang.AutoCloseable

    public interface Connection
    extends java.lang.AutoCloseable
    The Connection class is at the heart of the NATS Java client. Fundamentally a connection represents a single network connection to the NATS server.

    Each connection you create will result in the creation of a single socket and several threads:

    • A reader thread for taking data off the socket
    • A writer thread for putting data onto the socket
    • A timer thread for a few maintenance timers
    • A dispatch thread to handle request/reply traffic

    The connection has a status which can be checked using the getStatus method or watched using a ConnectionListener.

    Connections, by default, are configured to try to reconnect to the server if there is a network failure up to times. You can configure this behavior in the Options. Moreover, the options allows you to control whether reconnect happens in the same order every time, and the time to wait if trying to reconnect to the same server over and over.

    The list of servers used for connecting is provided by the Options. The list of servers used during reconnect can be an expanded list. This expansion comes from the connections most recent server. For example, if you connect to serverA, it can tell the connection "i know about serverB and serverC". If serverA goes down the client library will try to connect to serverA, serverB and serverC. Now, if the library connects to serverB, it may tell the client "i know about serverB and serverE". The client's list of servers, available from getServers() will now be serverA from the initial connect, serverB and serverE, the reference to serverC is lost.

    When a connection is closed the thread and socket resources are cleaned up.

    All outgoing messages are sent through the connection object using one of the two publish methods or the request method. When publishing you can specify a reply to subject which can be retrieved by the receiver to respond. The request method will handle this behavior itself, but it relies on getting the value out of a Future so may be less flexible than publish with replyTo set.

    Messages can be received in two ways. You can create a Subscription which will allow you to read messages synchronously using the nextMessage method or you can create a Dispatcher. The Dispatcher will create a thread to listen for messages on one or more subscriptions. The Dispatcher groups a set of subscriptions into a single listener thread that calls application code for each messages.

    Applications can use the flush method to check that published messages have made it to the server. However, this method initiates a round trip to the server and waits for the response so it should be used sparingly.

    The connection provides two listeners via the Options. The ConnectionListener can be used to listen for lifecycle events. This listener is required for connectAsynchronously, but otherwise optional. The ErrorListener provides three callback opportunities including slow consumers, error messages from the server and exceptions handled by the client library. These listeners can only be set at creation time using the options.

    Note: The publish methods take an array of bytes. These arrays will not be copied. This design choice is based on the common case of strings or objects being converted to bytes. Once a client can be sure a message was received by the NATS server it is theoretically possible to reuse that byte array, but this pattern should be treated as advanced and only used after thorough testing.

    • Nested Class Summary

      Nested Classes 
      Modifier and Type Interface Description
      static class  Connection.Status  
    • Method Summary

      All Methods Instance Methods Abstract Methods 
      Modifier and Type Method Description
      void close()
      Close the connection and release all blocking calls like flush and nextMessage.
      void closeDispatcher​(Dispatcher dispatcher)
      Close a dispatcher.
      Dispatcher createDispatcher​(MessageHandler handler)
      Create a Dispatcher for this connection.
      java.lang.String createInbox()  
      java.util.concurrent.CompletableFuture<java.lang.Boolean> drain​(java.time.Duration timeout)
      Drain tells the connection to process in flight messages before closing.
      void flush​(java.time.Duration timeout)
      Flush the connection's buffer of outgoing messages, including sending a protocol message to and from the server.
      java.lang.String getConnectedUrl()  
      java.lang.String getLastError()  
      long getMaxPayload()
      MaxPayload returns the size limit that a message payload can have.
      Options getOptions()  
      java.util.Collection<java.lang.String> getServers()
      Return the list of known server urls, including additional servers discovered after a connection has been established.
      Statistics getStatistics()  
      Connection.Status getStatus()
      Returns the connections current status.
      void publish​(java.lang.String subject, byte[] body)
      Send a message to the specified subject.
      void publish​(java.lang.String subject, java.lang.String replyTo, byte[] body)
      Send a request to the specified subject, providing a replyTo subject.
      java.util.concurrent.CompletableFuture<Message> request​(java.lang.String subject, byte[] data)
      Send a request.
      Message request​(java.lang.String subject, byte[] data, java.time.Duration timeout)
      Send a request and returns the reply or null.
      Subscription subscribe​(java.lang.String subject)
      Create a synchronous subscription to the specified subject.
      Subscription subscribe​(java.lang.String subject, java.lang.String queueName)
      Create a synchronous subscription to the specified subject and queue.
    • Method Detail

      • publish

        void publish​(java.lang.String subject,
                     byte[] body)
        Send a message to the specified subject. The message body will not be copied. The expected usage with string content is something like:
         nc = Nats.connect()
         nc.publish("destination", "message".getBytes("UTF-8"))
         
        where the sender creates a byte array immediately before calling publish. See publish() for more details on publish during reconnect.
        Parameters:
        subject - the subject to send the message to
        body - the message body
        Throws:
        java.lang.IllegalStateException - if the reconnect buffer is exceeded
      • publish

        void publish​(java.lang.String subject,
                     java.lang.String replyTo,
                     byte[] body)
        Send a request to the specified subject, providing a replyTo subject. The message body will not be copied. The expected usage with string content is something like:
         nc = Nats.connect()
         nc.publish("destination", "reply-to", "message".getBytes("UTF-8"))
         
        where the sender creates a byte array immediately before calling publish.

        During reconnect the client will try to buffer messages. The buffer size is set in the connect options, see reconnectBufferSize() with a default value of 8 * 1024 * 1024 bytes. If the buffer is exceeded an IllegalStateException is thrown. Applications should use this exception as a signal to wait for reconnect before continuing.

        Parameters:
        subject - the subject to send the message to
        replyTo - the subject the receiver should send the response to
        body - the message body
        Throws:
        java.lang.IllegalStateException - if the reconnect buffer is exceeded
      • request

        java.util.concurrent.CompletableFuture<Message> request​(java.lang.String subject,
                                                                byte[] data)
        Send a request. The returned future will be completed when the response comes back.
        Parameters:
        subject - the subject for the service that will handle the request
        data - the content of the message
        Returns:
        a Future for the response, which may be cancelled on error or timed out
      • request

        Message request​(java.lang.String subject,
                        byte[] data,
                        java.time.Duration timeout)
                 throws java.lang.InterruptedException
        Send a request and returns the reply or null. This version of request is equivalent to calling get on the future returned from request() with the timeout and handling the ExecutionException and TimeoutException.
        Parameters:
        subject - the subject for the service that will handle the request
        data - the content of the message
        timeout - the time to wait for a response
        Returns:
        the reply message or null if the timeout is reached
        Throws:
        java.lang.InterruptedException - if one is thrown while waiting, in order to propogate it up
      • subscribe

        Subscription subscribe​(java.lang.String subject)
        Create a synchronous subscription to the specified subject.

        Use the nextMessage method to read messages for this subscription.

        See createDispatcher for information about creating an asynchronous subscription with callbacks.

        As of 2.6.1 this method will throw an IllegalArgumentException if the subject contains whitespace.

        Parameters:
        subject - the subject to subscribe to
        Returns:
        an object representing the subscription
      • subscribe

        Subscription subscribe​(java.lang.String subject,
                               java.lang.String queueName)
        Create a synchronous subscription to the specified subject and queue.

        Use the nextMessage method to read messages for this subscription.

        See createDispatcher for information about creating an asynchronous subscription with callbacks.

        As of 2.6.1 this method will throw an IllegalArgumentException if either string contains whitespace.

        Parameters:
        subject - the subject to subscribe to
        queueName - the queue group to join
        Returns:
        an object representing the subscription
      • createDispatcher

        Dispatcher createDispatcher​(MessageHandler handler)
        Create a Dispatcher for this connection. The dispatcher can group one or more subscriptions into a single callback thread. All messages go to the same MessageHandler.

        Use the Dispatcher's Dispatcher.subscribe(String) and Dispatcher.subscribe(String, String) methods to add subscriptions.

         nc = Nats.connect()
         d = nc.createDispatcher((m) -> System.out.println(m)).subscribe("hello");
         
        Parameters:
        handler - The target for the messages
        Returns:
        a new Dispatcher
      • closeDispatcher

        void closeDispatcher​(Dispatcher dispatcher)
        Close a dispatcher. This will unsubscribe any subscriptions and stop the delivery thread.

        Once closed the dispatcher will throw an exception on subsequent subscribe or unsubscribe calls.

        Parameters:
        dispatcher - the dispatcher to close
      • flush

        void flush​(java.time.Duration timeout)
            throws java.util.concurrent.TimeoutException,
                   java.lang.InterruptedException
        Flush the connection's buffer of outgoing messages, including sending a protocol message to and from the server. Passing null is equivalent to passing 0, which will wait forever. If called while the connection is closed, this method will immediately throw a TimeoutException, regardless of the timeout. If called while the connection is disconnected due to network issues this method will wait for up to the timeout for a reconnect or close.
        Parameters:
        timeout - The time to wait for the flush to succeed, pass 0 to wait forever.
        Throws:
        java.util.concurrent.TimeoutException - if the timeout is exceeded
        java.lang.InterruptedException - if the underlying thread is interrupted
      • drain

        java.util.concurrent.CompletableFuture<java.lang.Boolean> drain​(java.time.Duration timeout)
                                                                 throws java.util.concurrent.TimeoutException,
                                                                        java.lang.InterruptedException
        Drain tells the connection to process in flight messages before closing. Drain initially drains all of the consumers, stopping incoming messages. Next, publishing is halted and a flush call is used to insure all published messages have reached the server. Finally the connection is closed. In order to drain subscribers, an unsub protocol message is sent to the server followed by a flush. These two steps occur before drain returns. The remaining steps occur in a background thread. This method tries to manage the timeout properly, so that if the timeout is 1 second, and the flush takes 100ms, the remaining steps have 900ms in the background thread. The connection will try to let all messages be drained, but when the timeout is reached the connection is closed and any outstanding dispatcher threads are interrupted. A future is used to allow this call to be treated as synchronous or asynchronous as needed by the application. The value of the future will be true if all of the subscriptions were drained in the timeout, and false otherwise. The future is completed after the connection is closed, so any connection handler notifications will happen before the future completes.
        Parameters:
        timeout - The time to wait for the drain to succeed, pass 0 to wait forever. Drain involves moving messages to and from the server so a very short timeout is not recommended. If the timeout is reached before the drain completes, the connection is simply closed, which can result in message loss.
        Returns:
        A future that can be used to check if the drain has completed
        Throws:
        java.lang.InterruptedException - if the thread is interrupted
        java.util.concurrent.TimeoutException - if the initial flush times out
      • close

        void close()
            throws java.lang.InterruptedException
        Close the connection and release all blocking calls like flush and nextMessage. If close() is called after drain it will wait up to the connection timeout to return, but it will not initiate a close. The drain takes precedence and will initiate the close.
        Specified by:
        close in interface java.lang.AutoCloseable
        Throws:
        java.lang.InterruptedException - if the thread, or one owned by the connection is interrupted during the close
      • getStatus

        Connection.Status getStatus()
        Returns the connections current status.
        Returns:
        the connection's status
      • getMaxPayload

        long getMaxPayload()
        MaxPayload returns the size limit that a message payload can have. This is set by the server configuration and delivered to the client upon connect.
        Returns:
        the maximum size of a message payload
      • getServers

        java.util.Collection<java.lang.String> getServers()
        Return the list of known server urls, including additional servers discovered after a connection has been established.
        Returns:
        this connection's list of known server URLs
      • getStatistics

        Statistics getStatistics()
        Returns:
        a wrapper for useful statistics about the connection
      • getOptions

        Options getOptions()
        Returns:
        the read-only options used to create this connection
      • getConnectedUrl

        java.lang.String getConnectedUrl()
        Returns:
        the url used for the current connection, or null if disconnected
      • getLastError

        java.lang.String getLastError()
        Returns:
        the error text from the last error sent by the server to this client
      • createInbox

        java.lang.String createInbox()
        Returns:
        a new inbox subject, can be used for directed replies from subscribers. These are guaranteed to be unique, but can be shared and subscribed to by others.