Ping/Pong Protocol

The client and server use a simple PING/PONG protocol to check that either of them are still connected to the other. On a regular interval the client will ping the server, which responds with a pong.

Ping/Pong Protocol - 图1

Once a configurable maximum of outstanding pings without a single pong reply is hit, the connection is closed as stale. Together these two values define a timeout for the connection which specifies how quickly the client will be notified of a problem. This will also help when there is a remote network partition where the operating system does not detect a socket error. Upon connection close, the client will attempt to reconnect. When it knows about other servers, these will be tried next.

In the presence of traffic, such as messages or client side pings, the server will not initiate the PING/PONG interaction.

On connections with a lot of traffic, the client will often figure out there is a problem between PINGS, and as a result the default PING interval is often on the order of minutes. To set the interval to 20s and limit outstanding pings to 5, thus forcing a closed connection after 100s of inactivity:

Go

  1. // Set Ping Interval to 20 seconds
  2. nc, err := nats.Connect("demo.nats.io", nats.Name("API Ping Example"), nats.PingInterval(20*time.Second), nats.MaxPingsOutstanding(5))
  3. if err != nil {
  4. log.Fatal(err)
  5. }
  6. defer nc.Close()
  7. // Do something with the connection

Java

  1. Options options = new Options.Builder().
  2. server("nats://demo.nats.io:4222").
  3. pingInterval(Duration.ofSeconds(20)). // Set Ping Interval
  4. maxPingsOut(5). // Set max pings in flight
  5. build();
  6. Connection nc = Nats.connect(options);
  7. // Do something with the connection
  8. nc.close();

JavaScript

  1. let nc = NATS.connect({
  2. pingInterval: 20*1000, //20s
  3. maxPingOut: 5,
  4. url: "nats://demo.nats.io:4222"
  5. });

Python

  1. nc = NATS()
  2. await nc.connect(
  3. servers=["nats://demo.nats.io:4222"],
  4. # Set Ping Interval to 20 seconds
  5. ping_interval=20,
  6. max_outstanding_pings=5,
  7. )
  8. # Do something with the connection.

Ruby

  1. require 'nats/client'
  2. NATS.start(ping_interval: 20, max_outstanding_pings: 5) do |nc|
  3. nc.on_reconnect do
  4. puts "Got reconnected to #{nc.connected_server}"
  5. end
  6. nc.on_disconnect do |reason|
  7. puts "Got disconnected! #{reason}"
  8. end
  9. # Do something with the connection
  10. end

TypeScript

  1. // will throw an exception if connection fails
  2. let nc = await connect({
  3. pingInterval: 20*1000, //20s
  4. maxPingOut: 5,
  5. url: "nats://demo.nats.io:4222"
  6. });
  7. nc.close();

C

  1. natsConnection *conn = NULL;
  2. natsOptions *opts = NULL;
  3. natsStatus s = NATS_OK;
  4. s = natsOptions_Create(&opts);
  5. if (s == NATS_OK)
  6. // Set Ping interval to 20 seconds (20,000 milliseconds)
  7. s = natsOptions_SetPingInterval(opts, 20000);
  8. if (s == NATS_OK)
  9. // Set the limit to 5
  10. s = natsOptions_SetMaxPingsOut(opts, 5);
  11. if (s == NATS_OK)
  12. s = natsConnection_Connect(&conn, opts);
  13. (...)
  14. // Destroy objects that were created
  15. natsConnection_Destroy(conn);
  16. natsOptions_Destroy(opts);