diff --git a/README.md b/README.md
index 9fa028a6..3f18b903 100644
--- a/README.md
+++ b/README.md
@@ -299,7 +299,7 @@ If you are running on MacOS, you can try issuing the command `make setup`, this
Enter the following commands to install additional software dependencies (if you used `make setup` you can skip this next step.)
-```bash
+```sh
npm install
npm install --global gulp-cli
```
@@ -308,14 +308,14 @@ npm install --global gulp-cli
Images and other source assets live in the `src` directory. The build workflow will resize images, and compile files in `src` and create the assets directory for hugo.
-```bash
+```sh
gulp build
```
The `gulp` command will do a build of the src directory and copy assets to the the `static` directory. This command will also run hugo and process the `content` directory creating a snapshot of the site in the `public` directory.
To preview your changes, run:
-```bash
+```sh
hugo server
```
@@ -327,7 +327,7 @@ Whenever `src` is modified, remember to run `gulp build` to update the `static`
Create a new blog post :
-```bash
+```sh
hugo new blog/my-blog-post.md
```
diff --git a/config.toml b/config.toml
index 9a9ccd0b..edd13d31 100644
--- a/config.toml
+++ b/config.toml
@@ -79,38 +79,38 @@ parent = "nats-streaming"
[[menu.main]]
name = "Documentation"
weight = 3
-identifier = "documentation"
-url = "/documentation"
+identifier = "doc"
+url = "/doc"
[[menu.main]]
-name = "Getting Started"
+name = "Getting Started With NATS"
weight = 1
-parent = "documentation"
+parent = "doc"
[[menu.main]]
-name = "Concepts"
+name = "Writing Applications"
weight = 2
-parent = "documentation"
+parent = "doc"
[[menu.main]]
-name = "Internals"
+name = "Managing the Server"
weight = 3
-parent = "documentation"
+parent = "doc"
[[menu.main]]
-name = "Server"
+name = "NATS Internals"
weight = 4
-parent = "documentation"
+parent = "doc"
[[menu.main]]
-name = "Streaming"
+name = "Event Streaming"
weight = 5
-parent = "documentation"
+parent = "doc"
[[menu.main]]
-name = "Tutorials"
+name = "Additional Documentation"
weight = 6
-parent = "documentation"
+parent = "doc"
[[menu.main]]
name = "Support"
diff --git a/content/documentation/_index.md b/content/doc/_index.md
similarity index 73%
rename from content/documentation/_index.md
rename to content/doc/_index.md
index cba3e36c..18cc5bb5 100644
--- a/content/documentation/_index.md
+++ b/content/doc/_index.md
@@ -1,28 +1,26 @@
+++
title = "NATS Documentation"
category = "documentation"
-showChildren=true
[menu.main]
- name = "Intro"
- weight = -100
- identifier = "intro"
- parent = "Getting Started"
+ name = "Introduction"
+ weight = 1
+ identifier = "doc-intro"
+ parent = "Getting Started With NATS"
+++
-
# NATS Introduction
[NATS](http://nats.io/) is an open-source, cloud-native messaging system. Companies like Apcera, Baidu, Siemens, VMware, HTC, and Ericsson rely on NATS for its highly performant and resilient messaging capabilities.
## NATS server
-NATS provides a lightweight [server](/documentation/server/gnatsd-intro/) that is written in the Go programming language. NATS is maintained by Synadia and an amazing OpenSource Ecosystem, find more at [GitHub](http://www.github.com/nats-io).
+NATS provides a lightweight [server](/doc/managing_the_server/installing/) that is written in the Go programming language. NATS is maintained by Synadia and an amazing OpenSource Ecosystem, find more at [GitHub](http://www.github.com/nats-io).
## NATS clients
There are several [client libraries](/download/) for NATS. Synadia actively maintains and supports the Go, Node, Ruby, Java, C, C# and NGINX C clients, and there are several community-provided clients.
-You can write your own client in any language you choose. NATS provides a simple, [text-based protocol](/documentation/internals/nats-protocol/) that makes [writing clients](/documentation/internals/nats-guide) a breeze.
+You can write your own client in any language you choose. NATS provides a simple, [text-based protocol](/doc/internals/nats-protocol/) that makes [writing clients](/doc/writing_applications/concepts) a breeze.
## NATS design goals
@@ -31,7 +29,7 @@ The core principles underlying NATS are performance, scalability, and ease-of-us
- Highly performant (fast)
- Always on and available (dial tone)
- Extremely lightweight (small footprint)
-- Support for multiple qualities of service (including guaranteed "at-least-once" delivery with [NATS Streaming](/documentation/streaming/nats-streaming-intro/))
+- Support for multiple qualities of service (including guaranteed "at-least-once" delivery with [NATS Streaming](/doc/streaming/nats-streaming-intro/))
- Support for various messaging models and use cases (flexible)
## NATS use cases
@@ -48,7 +46,7 @@ Some of the use cases and requirements that are ideal for NATS include:
- **Location transparency** - your applications need to scale to a very high number of instances spread out geographically, and you can't afford the fragility of tightly coupling your applications with detailed, specific endpoint-configuration information about where other applications are, and what type of data they are producing or consuming.
- **Fault tolerance** - your application needs to be highly resilient to network or other outages that may be beyond your control, and you need the underlying application data communication to seamlessly recover from connectivity outages
-With [NATS Streaming](/documentation/streaming/nats-streaming-intro/), a data streaming service for NATS, additional use cases include:
+With [NATS Streaming](/doc/streaming/nats-streaming-intro/), a data streaming service for NATS, additional use cases include:
- Event streaming with replay from specific time or sequence (or relevant offset)
- Durable subscriptions for transient clients
@@ -58,40 +56,40 @@ With [NATS Streaming](/documentation/streaming/nats-streaming-intro/), a data st
NATS supports various messaging models, including:
-- [Publish Subscribe](/documentation/concepts/nats-pub-sub/)
-- [Request Reply](/documentation/concepts/nats-req-rep/)
-- [Queueing](/documentation/concepts/nats-queueing/)
+- [Publish Subscribe](/doc/writing_applications/concepts#pubsub)
+- [Request Reply](/doc/writing_applications/concepts#reqrep)
+- [Queueing](/doc/writing_applications/concepts#queue)
## NATS features
NATS provides the following unique features:
-- [Pure pub-sub](/documentation/server/gnatsd-intro/)
+- [Pure pub-sub](/doc/managing_the_server/running)
- Never assumes the audience.
- Always "on" dial tone.
-- [Clustered mode server](/documentation/server/gnatsd-cluster/)
+- [Clustered mode server](/doc/managing_the_server/clustering)
- NATS servers can be clustered together.
- Distributed queueing across clusters.
- Cluster-aware clients.
-- [Auto-pruning of subscribers](/documentation/server/gnatsd-prune/)
+- [Auto-pruning of subscribers](/doc/managing_the_server/slow_consumers)
- To support scaling, NATS provides for auto-pruning of client connections.
- If a client app is slow consuming messages, NATS will cut off the client.
- If a client is not responsive within the ping-pong interval, the server cuts it off.
- Clients implement retry logic.
-- [Text-based protocol](/documentation/internals/nats-protocol/)
+- [Text-based protocol](/doc/internals/nats-protocol)
- Makes it easy to get started with new clients.
- Does not affect server performance.
- Can [Telnet](https://en.wikipedia.org/wiki/Telnet) directly to the server and send messages across the wire.
- Multiple qualities of service (QoS)
- At-most-once delivery (TCP level reliability) - NATS delivers messages to immediately eligible subscribers but does not persist the messages.
- - At-least-once delivery (via [NATS Streaming](/documentation/streaming/nats-streaming-intro/)) - Messages persisted until delivery to subscribers has been confirmed, or timeout expires, or storage exhausted.
-- Durable subscriptions (via [NATS Streaming](/documentation/streaming/nats-streaming-intro/))
+ - At-least-once delivery (via [NATS Streaming](/doc/streaming/nats-streaming-intro)) - Messages persisted until delivery to subscribers has been confirmed, or timeout expires, or storage exhausted.
+- Durable subscriptions (via [NATS Streaming](/doc/streaming/nats-streaming-intro))
- Subscription delivery state is maintained so that durable subscriptions may pick up where they left off during a previous session.
-- Event streaming service (via [NATS Streaming](/documentation/streaming/nats-streaming-intro/))
+- Event streaming service (via [NATS Streaming](/doc/streaming/nats-streaming-intro))
- Messages may be persisted to memory, file, or other secondary storage for later replay by time, sequence number, or relative offset.
-- Last/Initial value caching (via [NATS Streaming](/documentation/streaming/nats-streaming-intro/))
+- Last/Initial value caching (via [NATS Streaming](/doc/streaming/nats-streaming-intro))
- Subscription delivery can begin with the most recently published message for a subscription.
## NATS FAQs
-See our [FAQ page](/documentation/faq).
+See our [FAQ page](/doc/faq).
diff --git a/content/doc/additional_documentation/custom_dialer.md b/content/doc/additional_documentation/custom_dialer.md
new file mode 100644
index 00000000..e11d8455
--- /dev/null
+++ b/content/doc/additional_documentation/custom_dialer.md
@@ -0,0 +1,141 @@
++++
+title = "Advanced Connect and Custom Dialer"
+description = ""
+category = "tutorials"
+[menu.main]
+ name = "Custom Dialers"
+ weight = 3
+ identifier = "doc-custom-dialer"
+ parent = "Additional Documentation"
++++
+
+The Go NATS client features a [CustomDialer](https://godoc.org/github.com/nats-io/go-nats#CustomDialer) option which allows you to customize
+the connection logic against the NATS server without having to modify the internals
+of the client. For example, let's say that you want to make the client use the `context`
+package to use `DialContext` and be able to cancel connecting to NATS altogether with a deadline,
+you could then do define a Dialer implementation as follows:
+
+```go
+package main
+
+import (
+ "context"
+ "log"
+ "net"
+ "time"
+
+ "github.com/nats-io/go-nats"
+)
+
+type customDialer struct {
+ ctx context.Context
+ nc *nats.Conn
+ connectTimeout time.Duration
+ connectTimeWait time.Duration
+}
+
+func (cd *customDialer) Dial(network, address string) (net.Conn, error) {
+ ctx, cancel := context.WithTimeout(cd.ctx, cd.connectTimeout)
+ defer cancel()
+
+ for {
+ log.Println("Attempting to connect to", address)
+ if ctx.Err() != nil {
+ return nil, ctx.Err()
+ }
+
+ select {
+ case <-cd.ctx.Done():
+ return nil, cd.ctx.Err()
+ default:
+ d := &net.Dialer{}
+ if conn, err := d.DialContext(ctx, network, address); err == nil {
+ log.Println("Connected to NATS successfully")
+ return conn, nil
+ } else {
+ time.Sleep(cd.connectTimeWait)
+ }
+ }
+ }
+}
+```
+
+With the dialer implementation above, the NATS client will retry a number of times to connect
+to the NATS server until the context is no longer valid:
+
+```go
+func main() {
+ // Parent context cancels connecting/reconnecting altogether.
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+
+ var err error
+ var nc *nats.Conn
+ cd := &customDialer{
+ ctx: ctx,
+ connectTimeout: 10 * time.Second,
+ connectTimeWait: 1 * time.Second,
+ }
+ opts := []nats.Option{
+ nats.SetCustomDialer(cd),
+ nats.ReconnectWait(2 * time.Second),
+ nats.ReconnectHandler(func(c *nats.Conn) {
+ log.Println("Reconnected to", c.ConnectedUrl())
+ }),
+ nats.DisconnectHandler(func(c *nats.Conn) {
+ log.Println("Disconnected from NATS")
+ }),
+ nats.ClosedHandler(func(c *nats.Conn) {
+ log.Println("NATS connection is closed.")
+ }),
+ nats.NoReconnect(),
+ }
+ go func() {
+ nc, err = nats.Connect("127.0.0.1:4222", opts...)
+ }()
+
+WaitForEstablishedConnection:
+ for {
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ // Wait for context to be canceled either by timeout
+ // or because of establishing a connection...
+ select {
+ case <-ctx.Done():
+ break WaitForEstablishedConnection
+ default:
+ }
+
+ if nc == nil || !nc.IsConnected() {
+ log.Println("Connection not ready")
+ time.Sleep(200 * time.Millisecond)
+ continue
+ }
+ break WaitForEstablishedConnection
+ }
+ if ctx.Err() != nil {
+ log.Fatal(ctx.Err())
+ }
+
+ for {
+ if nc.IsClosed() {
+ break
+ }
+ if err := nc.Publish("hello", []byte("world")); err != nil {
+ log.Println(err)
+ time.Sleep(1 * time.Second)
+ continue
+ }
+ log.Println("Published message")
+ time.Sleep(1 * time.Second)
+ }
+
+ // Disconnect and flush pending messages
+ if err := nc.Drain(); err != nil {
+ log.Println(err)
+ }
+ log.Println("Disconnected")
+}
+```
\ No newline at end of file
diff --git a/content/documentation/tutorials/gnatsd-docker.md b/content/doc/additional_documentation/gnatsd-docker.md
similarity index 86%
rename from content/documentation/tutorials/gnatsd-docker.md
rename to content/doc/additional_documentation/gnatsd-docker.md
index 85e6e72d..aead7d17 100644
--- a/content/documentation/tutorials/gnatsd-docker.md
+++ b/content/doc/additional_documentation/gnatsd-docker.md
@@ -1,22 +1,16 @@
+++
-date = "2015-09-27"
-title = "Run NATS Docker Image"
+title = "Run the NATS Docker Image"
description = ""
category = "tutorials"
[menu.main]
- name = "Run NATS Docker Image"
- weight = 4
- identifier = "tutorial-gnatsd-docker"
- parent = "Tutorials"
+ name = "Docker"
+ weight = 8
+ identifier = "doc-gnatsd-docker"
+ parent = "Additional Documentation"
+++
-# Run NATS Server Docker Image
-
In this tutorial you run the [NATS server Docker image](https://hub.docker.com/_/nats/). The Docker image provides an instance of the [NATS Server](/documentation/server/gnatsd-intro/). Synadia actively maintains and supports the gnatsd Docker image. The NATS image is only 6 MB in size.
-
-## Instructions
-
**1. Set up Docker.**
See [Get Started with Docker](http://docs.docker.com/mac/started/) for guidance.
@@ -25,15 +19,15 @@ The easiest way to run Docker is to use the [Docker Toolbox](http://docs.docker.
**2. Run the gnatsd Docker image.**
-```
-$ docker run -p 4222:4222 -p 8222:8222 -p 6222:6222 --name gnatsd -ti nats:latest
+```sh
+> docker run -p 4222:4222 -p 8222:8222 -p 6222:6222 --name gnatsd -ti nats:latest
```
**3. Verify that the NATS server is running.**
You should see the following:
-```
+```sh
Unable to find image 'nats:latest' locally
latest: Pulling from library/nats
2d3d00b0941f: Pull complete
@@ -44,7 +38,7 @@ Status: Downloaded newer image for nats:latest
Followed by this, indicating that the NATS server is running:
-```
+```sh
[1] 2017/06/28 18:34:19.605144 [INF] Starting nats-server version 0.9.6
[1] 2017/06/28 18:34:19.605191 [INF] Starting http monitor on 0.0.0.0:8222
[1] 2017/06/28 18:34:19.605286 [INF] Listening for client connections on 0.0.0.0:4222
@@ -58,13 +52,13 @@ Notice how quickly the NATS server Docker image downloads. It is a mere 6 MB in
An easy way to test the client connection port is through using telnet.
-```
-$ telnet localhost 4222
+```sh
+> telnet localhost 4222
```
Expected result:
-```
+```sh
Trying ::1...
Connected to localhost.
Escape character is '^]'.
diff --git a/content/documentation/tutorials/go-install.md b/content/doc/additional_documentation/go-install.md
similarity index 92%
rename from content/documentation/tutorials/go-install.md
rename to content/doc/additional_documentation/go-install.md
index eeac0fdc..fadd76e9 100644
--- a/content/documentation/tutorials/go-install.md
+++ b/content/doc/additional_documentation/go-install.md
@@ -1,21 +1,16 @@
+++
-date = "2015-09-27"
-title = "Install Go"
+title = "Installing Go"
description = ""
category = "tutorials"
[menu.main]
- name = "Install Go"
+ name = "Installing Go"
weight = 1
- identifier = "tutorial-go-install"
- parent = "Tutorials"
+ identifier = "doc-install-golang"
+ parent = "Additional Documentation"
+++
-# Install Go for NATS
-
In this tutorial you set up your Go environment for running NATS.
-## Instructions
-
**1. Download Go.**
Go provides binary distributions for Mac OS X, Windows, and Linux. If you are using a different OS, you can download the Go source code and install from source.
@@ -40,13 +35,13 @@ The following instructions describe one way you can set your GOPATH. Refer to th
- Set the GOPATH environment variable for your workspace:
- ```
+ ```sh
export GOPATH=$HOME/go
```
- Also set the GOPATH/bin variable, which is used to run compiled Go programs.
- ```
+ ```sh
export PATH=$PATH:$GOPATH/bin
```
@@ -56,13 +51,13 @@ The following instructions describe one way you can set your GOPATH. Refer to th
- Create the GOPATH environment variable:
- ```
+ ```sh
set GOPATH=c:\Users\%USERNAME%\go
```
- Add the GOPATH\bin environment variable to your PATH:
- ```
+ ```sh
set PATH=%PATH%;%GOPATH%\bin
```
diff --git a/content/documentation/tutorials/nats-benchmarking.md b/content/doc/additional_documentation/nats-benchmarking.md
similarity index 78%
rename from content/documentation/tutorials/nats-benchmarking.md
rename to content/doc/additional_documentation/nats-benchmarking.md
index fdda2a4b..9bad192a 100644
--- a/content/documentation/tutorials/nats-benchmarking.md
+++ b/content/doc/additional_documentation/nats-benchmarking.md
@@ -1,126 +1,120 @@
+++
-date = "2015-09-27"
-title = "Benchmark and Tune NATS"
+title = "Benchmarking NATS"
description = ""
category = "tutorials"
[menu.main]
- name = "Benchmark and Tune NATS"
- weight = 10
- identifier = "tutorial-nats-benchmarking"
- parent = "Tutorials"
+ name = "Benchmarking"
+ weight = 6
+ identifier = "doc-nats-benchmarking"
+ parent = "Additional Documentation"
+++
-# Benchmark and Tune NATS
+NATS is fast and lightweight and places a priority on performance. NATS provides tools for measuring performance. In this tutorial you learn how to benchmark and tune NATS on your systems and environment.
-NATS is fast and lightweight and places a priority on performance. NATS provides tools for measuring and tuning performance. In this tutorial you learn how to benchmark and tune NATS.
-
-## Prerequisites
+#### Prerequisites
- [Set up your Go environment](/documentation/tutorials/go-install/)
- [Install the NATS server](/documentation/tutorials/gnatsd-install/)
-## Instructions
-
-### Start the NATS server with monitoring enabled
+#### Start the NATS server with monitoring enabled
-```
-gnatsd -m 8222
+```sh
+% gnatsd -m 8222
```
Verify that the NATS server starts successfully, as well as the HTTP monitor:
-```
+```sh
[18541] 2016/10/31 13:26:32.037819 [INF] Starting nats-server version 0.9.4
[18541] 2016/10/31 13:26:32.037912 [INF] Starting http monitor on 0.0.0.0:8222
[18541] 2016/10/31 13:26:32.037997 [INF] Listening for client connections on 0.0.0.0:4222
[18541] 2016/10/31 13:26:32.038020 [INF] Server is ready
```
-### Installing and running the benchmark utility
+#### Installing and running the benchmark utility
The NATS benchmark can be installed and run via Go. Ensure your golang environment is setup.
There are two approaches; you can either install the `nats-bench` utility in the directory specified in your `GOBIN` environment variable:
-```
-go install $GOPATH/src/github.com/nats-io/go-nats/examples/nats-bench.go
+
+```sh
+% go install $GOPATH/src/github.com/nats-io/go-nats/examples/nats-bench.go
```
... or you can simply run it via `go run`:
-```
-go run $GOPATH/src/github.com/nats-io/go-nats/examples/nats-bench.go
+```sh
+% go run $GOPATH/src/github.com/nats-io/go-nats/examples/nats-bench.go
```
*On windows use the % environment variable syntax, replacing `$GOPATH` with `%GOPATH%`.*
-For the purpose of this tutorial, we'll assume that you chose the first option, and that you've added the `GOBIN` environment variable to your `PATH`.
-
-### Usage
+For the purpose of this tutorial, we'll assume that you chose the first option, and that you've added the `GOBIN` environment variable to your `PATH`.
-The `nats-bench` utility is straightfoward to use. The optons are as follows:
+The `nats-bench` utility is straightforward to use. The options are as follows:
-```
-nats-bench -h
+```sh
+% nats-bench -h
Usage: nats-bench [-s server (nats://localhost:4222)] [--tls] [-np NUM_PUBLISHERS] [-ns NUM_SUBSCRIBERS] [-n NUM_MSGS] [-ms MESSAGE_SIZE] [-csv csvfile]
```
-The options are self-explanatory. Each publisher or subscriber runs in its own goroutine with its own NATS connection.
+The options are self-explanatory. Each publisher or subscriber runs in its own go routine with its own NATS connection.
-### Run a publisher throughput test
+#### Run a publisher throughput test
Let's run a test to see how fast a single publisher can publish one million 16 byte messages to the NATS server.
-```
-nats-bench -np 1 -n 100000 -ms 16 foo
+```sh
+% nats-bench -np 1 -n 100000 -ms 16 foo
```
The output tells you the number of messages and the number of payload bytes that the client was able to publish per second:
-```
+```sh
Starting benchmark [msgs=100000, msgsize=16, pubs=1, subs=0]
Pub stats: 7,055,644 msgs/sec ~ 107.66 MB/sec
```
Now increase the number of messages published:
-```
-nats-bench -np 1 -n 10000000 -ms 16 foo
+```sh
+% nats-bench -np 1 -n 10000000 -ms 16 foo
Starting benchmark [msgs=10000000, msgsize=16, pubs=1, subs=0]
Pub stats: 7,671,570 msgs/sec ~ 117.06 MB/sec
```
-### Run a publish/subscribe throughput test
+#### Run a publish/subscribe throughput test
When using both publishers and subscribers, `nats-bench` reports aggregate, as well as individual publish and subscribe throughput performance.
Let's look at throughput for a single publisher with a single subscriber:
-```
-nats-bench -np 1 -ns 1 -n 100000 -ms 16 foo
+```sh
+% nats-bench -np 1 -ns 1 -n 100000 -ms 16 foo
```
Note that the output shows the aggregate throughput as well as the individual publisher and subscriber performance:
-```
+```sh
Starting benchmark [msgs=100000, msgsize=16, pubs=1, subs=1]
NATS Pub/Sub stats: 2,009,230 msgs/sec ~ 30.66 MB/sec
Pub stats: 1,076,537 msgs/sec ~ 16.43 MB/sec
Sub stats: 1,004,615 msgs/sec ~ 15.33 MB/sec
```
-### Run a 1:N throughput test
+#### Run a 1:N throughput test
When specifying multiple publishers, or multiple subscribers, `nats-bench` will also report statistics for each publisher and subscriber individually, along with min/max/avg and standard deviation.
Let's increase both the number of messages, and the number of subscribers.:
-```
-nats-bench -np 1 -ns 5 -n 10000000 -ms 16 foo
+```sh
+% nats-bench -np 1 -ns 5 -n 10000000 -ms 16 foo
```
Output:
-```
+```sh
Starting benchmark [msgs=10000000, msgsize=16, pubs=1, subs=5]
NATS Pub/Sub stats: 5,730,851 msgs/sec ~ 87.45 MB/sec
Pub stats: 955,279 msgs/sec ~ 14.58 MB/sec
@@ -133,19 +127,19 @@ NATS Pub/Sub stats: 5,730,851 msgs/sec ~ 87.45 MB/sec
min 955,150 | avg 955,154 | max 955,157 | stddev 2 msgs
```
-### Run a N:M throughput test
+#### Run a N:M throughput test
When more than 1 publisher is specified, `nats-bench` evenly distributes the total number of messages (`-n`) across the number of publishers (`-np`).
Now let's increase the number of publishers and examine the output:
-```
-nats-bench -np 5 -ns 5 -n 10000000 -ms 16 foo
+```sh
+% nats-bench -np 5 -ns 5 -n 10000000 -ms 16 foo
```
The output:
-```
+```sh
Starting benchmark [msgs=10000000, msgsize=16, pubs=5, subs=5]
NATS Pub/Sub stats: 6,716,465 msgs/sec ~ 102.49 MB/sec
Pub stats: 1,119,653 msgs/sec ~ 17.08 MB/sec
@@ -163,4 +157,3 @@ NATS Pub/Sub stats: 6,716,465 msgs/sec ~ 102.49 MB/sec
[5] 1,119,430 msgs/sec ~ 17.08 MB/sec (10000000 msgs)
min 1,119,430 | avg 1,119,449 | max 1,119,466 | stddev 12 msgs
```
-
diff --git a/content/documentation/tutorials/nats-docker-swarm.md b/content/doc/additional_documentation/nats-docker-swarm.md
similarity index 80%
rename from content/documentation/tutorials/nats-docker-swarm.md
rename to content/doc/additional_documentation/nats-docker-swarm.md
index 9f1368fa..c2aad61a 100644
--- a/content/documentation/tutorials/nats-docker-swarm.md
+++ b/content/doc/additional_documentation/nats-docker-swarm.md
@@ -4,32 +4,32 @@ title = "Using NATS with Docker Swarm"
description = ""
category = "tutorials"
[menu.main]
- name = "Using NATS with Docker Swarm"
- weight = 4
- identifier = "tutorial-nats-docker-swarm"
- parent = "Tutorials"
+ name = "Docker Swarm"
+ weight = 10
+ identifier = "doc-docker-swarm"
+ parent = "Additional Documentation"
+++
-# Using NATS with Docker Swarm
-
-# Step 1:
+#### Step 1:
Create an overlay network for the cluster (in this example, `nats-cluster-example`), and instantiate an initial NATS server.
First create an overlay network:
-```
-docker network create --driver overlay nats-cluster-example
+
+```sh
+% docker network create --driver overlay nats-cluster-example
```
Next instantiate an initial "seed" server for a NATS cluster listening for other servers to join route to it on port 6222:
-```
-docker service create --network nats-cluster-example --name nats-cluster-node-1 nats:1.0.0 -cluster nats://0.0.0.0:6222 -DV
+
+```sh
+% docker service create --network nats-cluster-example --name nats-cluster-node-1 nats:1.0.0 -cluster nats://0.0.0.0:6222 -DV
```
-# Step 2:
+#### Step 2:
The 2nd step is to create another service which connects to the NATS server within the overlay network. Note that we connect to to the server at `nats-cluster-node-1`:
-```
-docker service create --name ruby-nats --network nats-cluster-example wallyqs/ruby-nats:ruby-2.3.1-nats-v0.8.0 -e '
+```sh
+% docker service create --name ruby-nats --network nats-cluster-example wallyqs/ruby-nats:ruby-2.3.1-nats-v0.8.0 -e '
NATS.on_error do |e|
puts "ERROR: #{e}"
end
@@ -54,25 +54,25 @@ docker service create --name ruby-nats --network nats-cluster-example wallyqs/ru
end'
```
-# Step 3:
+#### Step 3:
Now you can add more nodes to the Swarm cluster via more docker services, referencing the seed server in the `-routes` parameter:
-```
-docker service create --network nats-cluster-example --name nats-cluster-node-2 nats:1.0.0 -cluster nats://0.0.0.0:6222 -routes nats://nats-cluster-node-1:6222 -DV
+```sh
+% docker service create --network nats-cluster-example --name nats-cluster-node-2 nats:1.0.0 -cluster nats://0.0.0.0:6222 -routes nats://nats-cluster-node-1:6222 -DV
```
In this case, `nats-cluster-node-1` is seeding the rest of the cluster through the autodiscovery feature. Now NATS servers `nats-cluster-node-1` and `nats-cluster-node-2` are clustered together.
Add in more replicas of the subscriber:
-```
-docker service scale ruby-nats=3
+```sh
+% docker service scale ruby-nats=3
```
Then confirm the distribution on the Docker Swarm cluster:
-```
-docker service ps ruby-nats
+```sh
+% docker service ps ruby-nats
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR
25skxso8honyhuznu15e4989m ruby-nats.1 wallyqs/ruby-nats:ruby-2.3.1-nats-v0.8.0 node-1 Running Running 2 minutes ago
0017lut0u3wj153yvp0uxr8yo ruby-nats.2 wallyqs/ruby-nats:ruby-2.3.1-nats-v0.8.0 node-1 Running Running 2 minutes ago
@@ -81,7 +81,7 @@ ID NAME IMAGE
The sample output after adding more NATS server nodes to the cluster, is below - and notice that the client is *dynamically* aware of more nodes being part of the cluster via auto discovery!
-```
+```sh
[2016-08-15 12:51:52 +0000] Saying hi (servers in pool: [{:uri=>#, :was_connected=>true, :reconnect_attempts=>0}]
[2016-08-15 12:51:53 +0000] Saying hi (servers in pool: [{:uri=>#, :was_connected=>true, :reconnect_attempts=>0}]
[2016-08-15 12:51:54 +0000] Saying hi (servers in pool: [{:uri=>#, :was_connected=>true, :reconnect_attempts=>0}]
@@ -89,15 +89,17 @@ The sample output after adding more NATS server nodes to the cluster, is below -
```
Sample output after adding more workers which can reply back (since ignoring own responses):
-```
+
+```sh
[2016-08-15 16:06:26 +0000] Received reply - world
[2016-08-15 16:06:26 +0000] Received reply - world
[2016-08-15 16:06:27 +0000] Received greeting - hi - _INBOX.b8d8c01753d78e562e4dc561f1
[2016-08-15 16:06:27 +0000] Received greeting - hi - _INBOX.4c35d18701979f8c8ed7e5f6ea
```
-# And so forth...
+
+### And so forth...
From here you can experiment adding to the NATS cluster by simply adding servers with new service names, that route to the seed server `nats-cluster-node-1`. As you've seen above, clients will automatically be updated to know that new servers are available in the cluster.
-```
-docker service create --network nats-cluster-example --name nats-cluster-node-3 nats:1.0.0 -cluster nats://0.0.0.0:6222 -routes nats://nats-cluster-node-1:6222 -DV
+```sh
+% docker service create --network nats-cluster-example --name nats-cluster-node-3 nats:1.0.0 -cluster nats://0.0.0.0:6222 -routes nats://nats-cluster-node-1:6222 -DV
```
\ No newline at end of file
diff --git a/content/documentation/tutorials/nats-kubernetes.md b/content/doc/additional_documentation/nats-kubernetes.md
similarity index 90%
rename from content/documentation/tutorials/nats-kubernetes.md
rename to content/doc/additional_documentation/nats-kubernetes.md
index 52aec42b..256e04e3 100644
--- a/content/documentation/tutorials/nats-kubernetes.md
+++ b/content/doc/additional_documentation/nats-kubernetes.md
@@ -4,14 +4,12 @@ title = "Using NATS with Kubernetes"
description = ""
category = "tutorials"
[menu.main]
- name = "Using NATS with Kubernetes"
- weight = 4
- identifier = "tutorial-nats-kubernetes"
- parent = "Tutorials"
+ name = "Kubernetes"
+ weight = 9
+ identifier = "doc-nats-kubernetes"
+ parent = "Additional Documentation"
+++
-# Using NATS with Kubernetes
-
NATS and Kubernetes are extremely popular together. Both are cloud native systems designed to handle modern, distributed workloads. There are a variety of methods you can use to run NATS and Kubernetes - including many examples from the broader developer community. We are going to take a look at some of those below.
## Running a NATS Cluster on top of Kubernetes
diff --git a/content/documentation/tutorials/nats-minio.md b/content/doc/additional_documentation/nats-minio.md
similarity index 76%
rename from content/documentation/tutorials/nats-minio.md
rename to content/doc/additional_documentation/nats-minio.md
index 5e7e33df..845253e8 100644
--- a/content/documentation/tutorials/nats-minio.md
+++ b/content/doc/additional_documentation/nats-minio.md
@@ -4,31 +4,32 @@ title = "Using NATS with Minio"
description = ""
category = "tutorials"
[menu.main]
- name = "Using NATS with Minio"
- weight = 4
- identifier = "tutorial-nats-minio"
- parent = "Tutorials"
+ name = "Minio"
+ weight = 12
+ identifier = "doc-nats-minio"
+ parent = "Additional Documentation"
+++
-# Using NATS with Minio
-
-## NATS and Minio
[Minio](https://www.minio.io) is a Golang-based object store, increasingly popular for cloud native deployments. Minio is S3 compatible, and runs across a wide variety of platforms.
This demonstration will show you how to run a Minio object store on a local machine, configure a local NATS instance, and finally replicate objects to other clouds.
-## Step 1: Install and run NATS Server
+#### Step 1: Install and run NATS Server
+
`go get github.com/nats-io/gnatsd`
-## Step 2: Install Minio
+#### Step 2: Install Minio
+
`go get github.com/minio/minio`
-## Step 3: Configure Minio to use NATS for event subscription
-edit `~/.minio/config.json`
+#### Step 3: Configure Minio to use NATS for event subscription
+
+Edit `~/.minio/config.json`
Enable NATS in the configuration by setting: `"nats"."1"."enable": true`
For example:
+
```json
{
"nats": {
@@ -41,18 +42,22 @@ For example:
}
```
-## Step 4: Run Minio
+#### Step 4: Run Minio
+
`minio server ~/minio-tmp/`
-## Step 5: Run Minio-NATS
+#### Step 5: Run Minio-NATS
+
`go run minionats/main.go -remote s3://accessKeyId:accessSecretKey@host:port -local s3://accessKeyId:accessSecretKey@host:port`
-## Step 6: Try it out!
-* Go into your test bucket [Minio Browser](http://localhost:9000/minio/minio-nats-example/) your [S3 Bucket](https://console.aws.amazon.com/s3/buckets/minio-nats-example)
-* Now when you upload or delete a file in Minio, these changes will be replicated on your S3 Bucket!
+#### Step 6: Try it out!
+
+- Go into your test bucket [Minio Browser](http://localhost:9000/minio/minio-nats-example/) your [S3 Bucket](https://console.aws.amazon.com/s3/buckets/minio-nats-example)
+- Now when you upload or delete a file in Minio, these changes will be replicated on your S3 Bucket!
## Usage flags
-```
+
+```sh
Usage of demo-minio-nats:
-bucket string
bucket to test with (default "minio-nats-example")
diff --git a/content/doc/additional_documentation/nats-pub-sub.md b/content/doc/additional_documentation/nats-pub-sub.md
new file mode 100644
index 00000000..48ef0fc4
--- /dev/null
+++ b/content/doc/additional_documentation/nats-pub-sub.md
@@ -0,0 +1,196 @@
++++
+date = "2015-09-27"
+title = "Explore NATS Pub Sub"
+description = ""
+category = "tutorials"
+[menu.main]
+ name = "Explore Pub-Sub"
+ weight = 3
+ identifier = "doc-nats-pub-sub"
+ parent = "Additional Documentation"
++++
+
+NATS is a [publish subscribe messaging system](/doc/writing_applications/concepts). Subscribers listening on a subject name receive messages on that subject. If the subscriber is not actively listening on the subject, the message is not received. Subscribers can use the wildcard subjects `*` to match a single token to match the tail of a subject.
+
+
+
+#### Prerequisites
+
+- [Set up your Go environment](/documentation/tutorials/go-install/)
+- [Installed the NATS server](/documentation/tutorials/gnatsd-install/)
+
+#### 1. Start the NATS server
+
+```sh
+% gnatsd
+```
+
+When the server starts successfully, you will see the following messages:
+
+```sh
+[1] 2015/08/12 15:18:22.301550 [INF] Starting gnatsd version 0.6.4
+[1] 2015/08/12 15:18:22.301762 [INF] Listening for client connections on 0.0.0.0:4222
+[1] 2015/08/12 15:18:22.301769 [INF] gnatsd is ready
+```
+
+The NATS server listens for client connections on TCP Port 4222.
+
+#### 2. Start a shell or command prompt session
+
+You will use this session to run an example NATS client subscriber program.
+
+#### 3. CD to the Go client examples directory
+
+```sh
+% cd $GOPATH/src/github.com/nats-io/nats/examples
+```
+
+#### 4. Run the client subscriber program
+
+```sh
+% go run nats-sub.go
+```
+
+Where `` is a subject to listen on. A valid subject is a string that is unique in the system.
+
+For example:
+
+```sh
+% go run nats-sub.go msg.test
+```
+
+You should see the message: *Listening on [msg.test]*
+
+#### 5. Start another shell or command prompt session
+
+You will use this session to run a NATS publisher client.
+
+#### 6. CD to the examples directory
+
+```sh
+% cd $GOPATH/src/github.com/nats-io/nats/examples
+```
+
+#### 7. Publish a NATS message
+
+```sh
+% go run nats-pub.go
+```
+
+Where `` is the subject name and `` is the text to publish.
+
+For example:
+
+```sh
+% go run nats-pub.go msg.test hello
+```
+
+or
+
+```sh
+% go run nats-pub.go msg.test "NATS MESSAGE"
+```
+
+#### 7. Verify message publication and receipt
+
+You should see that the publisher sends the message: *Published [msg.test] : 'NATS MESSAGE'*
+
+And that the subscriber receives the message: *[#1] Received on [msg.test]: 'NATS MESSAGE'*
+
+Note that if the receiver does not get the message, check that you are using the same subject name for the publisher and the subscriber.
+
+#### 8. Publish another message
+
+```sh
+% go run nats-pub.go msg.test "NATS MESSAGE 2"
+```
+
+You should see that the subscriber receive message 2. Note that the message count is incremented each time your subscribing client receives a message on that subject:
+
+#### 9. Start another shell or command prompt session
+
+You will use this session to run a second NATS subscriber.
+
+#### 10. CD to the examples directory
+
+```sh
+% cd $GOPATH/src/github.com/nats-io/nats/examples
+```
+
+#### 11. Subscribe to the message
+
+```sh
+% go run nats-sub.go msg.test
+```
+
+#### 12. Publish another message using the publisher client
+
+```sh
+% go run nats-pub.go msg.test "NATS MESSAGE 3"
+```
+
+Verify that both subscribing clients receive the message.
+
+#### 13. Start another shell or command prompt session
+
+You will use this session to run a third NATS subscriber.
+
+#### 14. CD to the examples directory
+
+```sh
+% cd $GOPATH/src/github.com/nats-io/nats/examples
+```
+
+#### 15. Subscribe to a different message
+
+```sh
+% go run nats-sub.go msg.test.new
+```
+
+All the but last subscriber receives the message. Why? Because that subscriber is not listening on the message subject used by the publisher.
+
+#### 16. Update the last subscriber to use a wildcard
+
+NATS supports the use of wildcard characters for message subscribers. (You cannot publish a message using a wildcard subject.)
+
+Change the last subscriber the listen on msg.* and run it:
+
+```sh
+% go run nats-sub.go msg.*
+```
+
+#### 17. Publish another message
+
+This time, all three subscribing clients should receive the message.
diff --git a/content/documentation/tutorials/nats-queueing.md b/content/doc/additional_documentation/nats-queueing.md
similarity index 76%
rename from content/documentation/tutorials/nats-queueing.md
rename to content/doc/additional_documentation/nats-queueing.md
index 7fe66fb7..fc2ec7f1 100644
--- a/content/documentation/tutorials/nats-queueing.md
+++ b/content/doc/additional_documentation/nats-queueing.md
@@ -4,20 +4,18 @@ title = "Explore NATS Queueing"
description = ""
category = "tutorials"
[menu.main]
- name = "Explore NATS Queueing"
- weight = 7
- identifier = "tutorial-nats-queueing"
- parent = "Tutorials"
+ name = "Explore Queueing"
+ weight = 5
+ identifier = "doc-nats-queueing"
+ parent = "Additional Documentation"
+++
-# Explore NATS Queueing
+NATS supports [message queueing](/doc/writing_applications/concepts) using queue groups. Subscribers register a queue group name. A single subscriber in the group is randomly selected to receive the message.
-NATS supports [message queueing](/documentation/concepts/nats-queueing/) using queue groups. Subscribers register a queue group name. A single subscriber in the group is randomly selected to receive the message.
+#### Prerequisites
-## Prerequisites
-
-- [Set up your Go environment](/documentation/tutorials/go-install/)
-- [Installed the NATS server](/documentation/tutorials/gnatsd-install/)
+- [Set up your Go environment](/doc/additional_documentation/go-install)
+- [Installed the NATS server](/doc/managing_the_server/installing)
## Instructions
diff --git a/content/documentation/tutorials/nats-req-rep.md b/content/doc/additional_documentation/nats-req-rep.md
similarity index 54%
rename from content/documentation/tutorials/nats-req-rep.md
rename to content/doc/additional_documentation/nats-req-rep.md
index a3c5c676..099d0b01 100644
--- a/content/documentation/tutorials/nats-req-rep.md
+++ b/content/doc/additional_documentation/nats-req-rep.md
@@ -4,51 +4,47 @@ title = "Explore NATS Request Reply"
description = ""
category = "tutorials"
[menu.main]
- name = "Explore NATS Request Reply"
- weight = 6
- identifier = "tutorial-nats-req-rep"
- parent = "Tutorials"
+ name = "Explore Request Reply"
+ weight = 4
+ identifier = "doc-nats-req-rep"
+ parent = "Additional Documentation"
+++
-# Explore NATS Request Reply
+NATS supports [request reply messaging](/doc/writing_applications/concepts). In this tutorial you explore how to exchange point-to-point messages using NATS.
-NATS supports [request reply messaging](/documentation/concepts/nats-req-rep/). In this tutorial you explore how to exchange point-to-point messages using NATS.
-
-## Prerequisites
+#### Prerequisites
- [Set up your Go environment](/documentation/tutorials/go-install/)
- [Installed the NATS server](/documentation/tutorials/gnatsd-install/)
-## Instructions
-
-**1. Start the NATS server.**
+#### 1. Start the NATS server
-```
-gnatsd
+```sh
+% gnatsd
```
-**2. Start two terminal sessions.**
+#### 2. Start two terminal sessions
You will use these sessions to run the NATS request and reply clients.
-**3. Change to the examples directory.**
+#### 3. Change to the examples directory
-```
-cd $GOPATH/src/github.com/nats-io/nats/examples
+```sh
+% cd $GOPATH/src/github.com/nats-io/nats/examples
```
-**4. In one terminal, run the reply client listener.**
+#### 4. In one terminal, run the reply client listener
-```
-go run nats-rply.go foo "this is my response"
+```sh
+% go run nats-rply.go foo "this is my response"
```
You should see the message `Receiver is listening`, and that the NATS receiver client is listening on the "help.please" subject. The reply client acts as a receiver, listening for message requests. In NATS, the receiver is a subscriber.
-**5. In the other terminal, run the request client.**
+#### 5. In the other terminal, run the request client
-```
-go run nats-req.go foo "request payload"
+```sh
+% go run nats-req.go foo "request payload"
```
The NATS requestor client makes a request by sending the message "some message" on the “help.please” subject.
diff --git a/content/doc/additional_documentation/nats-source.md b/content/doc/additional_documentation/nats-source.md
new file mode 100644
index 00000000..9094b7ad
--- /dev/null
+++ b/content/doc/additional_documentation/nats-source.md
@@ -0,0 +1,72 @@
++++
+title = "Build the NATS Server from Source"
+description = ""
+category = "tutorials"
+[menu.main]
+ name = "Build gnatsd From Source"
+ weight = 2
+ identifier = "doc-nats-source"
+ parent = "Additional Documentation"
++++
+
+The NATS server code is available as open source software under the Apache-2.0 license. You can build the source to run the NATS server on any platform supported by Go. The NATS server code requires at least version 1.4 of Go. You are encouraged to run the latest stable release of Go.
+
+#### Prerequisite
+
+- [Set up your Go environment](/documentation/tutorials/go-install/)
+
+#### 1. Verify your Go environment
+
+Run the following command to verify that you are using at least Go 1.5.
+
+```sh
+% go version
+```
+
+#### 2. Create and change into $GOPATH/src/github.com/nats-io directory
+
+```sh
+%cd $GOPATH/src
+
+% mkdir -p github\.com/nats-io && cd github.com/nats-io
+```
+
+#### 3. Clone the NATS server repository
+
+```sh
+% git clone git@github.com:nats-io/gnatsd.git
+```
+
+#### 4. Change to the `gnatsd` directory you cloned
+
+```sh
+%cd $GOPATH/src/github.com/nats-io/gnatsd
+```
+
+#### 5. View the NATS server source code
+
+View the `main.go` file.
+
+```sh
+% cat main.go
+```
+
+#### 6. Build the server from source
+
+Run `go build` from inside the `gnatsd` directory.
+
+```sh
+% cd gnatsd
+
+% go build
+```
+
+A successful build run produces no messages and creates an executable called `gnatsd` in this directory.
+
+You can invoke this binary, with no options and no configuration file for local testing. To start a server with acceptable production defaults please read our [README.md](https://github.com/nats-io/gnatsd#command-line-arguments)
+
+#### 7. Start nats-server
+
+```sh
+% ./gnatsd
+```
diff --git a/content/documentation/tutorials/nats-streaming-swarm.md b/content/doc/additional_documentation/nats-streaming-swarm.md
similarity index 91%
rename from content/documentation/tutorials/nats-streaming-swarm.md
rename to content/doc/additional_documentation/nats-streaming-swarm.md
index 6fcb6cbb..af442e95 100644
--- a/content/documentation/tutorials/nats-streaming-swarm.md
+++ b/content/doc/additional_documentation/nats-streaming-swarm.md
@@ -4,25 +4,23 @@ title = "Using NATS Streaming with Docker Swarm"
description = ""
category = "tutorials"
[menu.main]
- name = "Using NATS Streaming with Docker Swarm"
- weight = 4
- identifier = "tutorial-nats-streaming-docker-swarm"
- parent = "Tutorials"
+ name = "Streaming with Docker Swarm"
+ weight = 11
+ identifier = "doc-nats-streaming-docker-swarm"
+ parent = "Additional Documentation"
+++
-# Using NATS Streaming with Docker Swarm
-
-# Step 1:
+#### Step 1:
Create an overlay network for the NATS & NATS Streaming cluster (in this example, `nats-streaming-example`).
Notice we added the `--attachable` option which will allow other containers to join the network which will be
done at the end to confirm that can connect to the cluster.
```sh
-docker network create --driver overlay --attachable nats-streaming-example
+% docker network create --driver overlay --attachable nats-streaming-example
```
-# Step 2:
+#### Step 2:
Next create the NATS cluster which will be used by the NATS Streaming cluster.
@@ -35,7 +33,7 @@ for i in `seq 1 3`; do
done
```
-# Step 3:
+#### Step 3:
Now that there is a NATS cluster available to connect, create the NATS Streaming cluster of three nodes as follows:
@@ -49,7 +47,7 @@ for i in `seq 1 3`; do
done
```
-# Step 4:
+#### Step 4:
Next, confirm that it is possible to publish and replay messages via NATS Streaming by attaching a container
to the same network where both NATS and NATS Streaming exist. Below you can find an example session of doing so,
diff --git a/content/documentation/tutorials/nats-top.md b/content/doc/additional_documentation/nats-top.md
similarity index 82%
rename from content/documentation/tutorials/nats-top.md
rename to content/doc/additional_documentation/nats-top.md
index a1aa4016..2536221d 100644
--- a/content/documentation/tutorials/nats-top.md
+++ b/content/doc/additional_documentation/nats-top.md
@@ -1,53 +1,49 @@
+++
date = "2015-09-27"
-title = "Use NATS Top to Monitor NATS"
+title = "Using NATS Top to Monitor NATS"
description = ""
category = "tutorials"
[menu.main]
- name = "Use NATS Top to Monitor NATS"
- weight = 9
- identifier = "tutorial-nats-top"
- parent = "Tutorials"
+ name = "Explore nats-top"
+ weight = 7
+ identifier = "doc-nats-top"
+ parent = "Additional Documentation"
+++
-# Use NATS Top to Monitor NATS
+You can use [nats-top](/doc/managing_the_server/statistics) to monitor in realtime NATS server connections and message statistics.
-You can use [nats-top](/documentation/server/gnatsd-top) to monitor in realtime NATS server connections and message statistics.
-
-## Prerequisites
+#### Prerequisites
- [Set up your Go environment](/documentation/tutorials/go-install/)
- [Installed the NATS server](/documentation/tutorials/gnatsd-install/)
-## Instructions
-
-**1. Install nats-top.**
+#### 1. Install nats-top
-```
-go get github.com/nats-io/nats-top
+```sh
+% go get github.com/nats-io/nats-top
```
You may need to run the following instead:
-```
-sudo -E go get github.com/nats-io/nats-top
+```sh
+% sudo -E go get github.com/nats-io/nats-top
```
-**2. Start the NATS server with monitoring enabled.**
+#### 2. Start the NATS server with monitoring enabled
-```
-gnatsd -m 8222
+```sh
+% gnatsd -m 8222
```
-**3. Start nats-top.**
+#### 3. Start nats-top
-```
-nats-top
+```sh
+% nats-top
```
Result:
-```
+```sh
gnatsd version 0.6.6 (uptime: 2m2s)
Server:
Load: CPU: 0.0% Memory: 6.3M Slow Consumers: 0
@@ -58,15 +54,15 @@ Connections: 0
HOST CID SUBS PENDING MSGS_TO MSGS_FROM BYTES_TO BYTES_FROM LANG VERSION
```
-**4. Run NATS client programs.**
+#### 4. Run NATS client programs
Run some NATS client programs and exchange messages.
-For the best experience, you will want to run multiple subscribers, at least 2 or 3. Refer to the [example pub-sub clients](/documentation/tutorials/nats-pub-sub).
+For the best experience, you will want to run multiple subscribers, at least 2 or 3. Refer to the [example pub-sub clients](/doc/additional_documentation/nats-pub-sub).
-**5. Check nats-top for statistics.**
+#### 5. Check nats-top for statistics
-```
+```sh
gnatsd version 0.6.6 (uptime: 30m51s)
Server:
Load: CPU: 0.0% Memory: 10.3M Slow Consumers: 0
@@ -80,11 +76,11 @@ Connections: 3
::1:58953 39 1 0 21 0 105 0 go 1.1.0
```
-**6. Sort nats-top statistics.**
+#### 6. Sort nats-top statistics
In nats-top, enter the command `o` followed by the option, such as `bytes_to`. You see that nats-top sorts the BYTES_TO column in ascending order.
-```
+```sh
gnatsd version 0.6.6 (uptime: 45m40s)
Server:
Load: CPU: 0.0% Memory: 10.4M Slow Consumers: 0
@@ -98,7 +94,7 @@ Connections: 3
::1:59342 90 1 0 0 0 0 0 go 1.1.0
```
-**7. Use different sort options.**
+#### 7. Use different sort options
Use some different sort options to explore nats-top, such as:
@@ -106,11 +102,11 @@ Use some different sort options to explore nats-top, such as:
You can also set the sort option on the command line using the `-sort` flag. For example: `nats-top -sort bytes_to`.
-**8. Display the registered subscriptions.**
+#### 8. Display the registered subscriptions.
In nats-top, enter the command `s` to toggle displaying connection subscriptions. When enabled, you see the subscription subject in nats-top table:
-```
+```sh
gnatsd version 0.6.6 (uptime: 1h2m23s)
Server:
Load: CPU: 0.0% Memory: 10.4M Slow Consumers: 0
@@ -124,21 +120,21 @@ Connections: 3
::1:59817 124 1 0 0 0 0 0 go 1.1.0 foo
```
-**9. Quit nats-top.**
+#### 9. Quit nats-top
Use the `q` command to quit nats-top.
-**10. Restart nats-top with a specified query.**
+#### 10. Restart nats-top with a specified query
For example, to query for the connection with largest number of subscriptions:
-```
-nats-top -n 1 -sort subs
+```sh
+% nats-top -n 1 -sort subs
```
Result: nats-top displays only the client connection with the largest number of subscriptions:
-```
+```sh
gnatsd version 0.6.6 (uptime: 1h7m0s)
Server:
Load: CPU: 0.0% Memory: 10.4M Slow Consumers: 0
diff --git a/content/documentation/contributing.md b/content/doc/contributing.md
similarity index 50%
rename from content/documentation/contributing.md
rename to content/doc/contributing.md
index 34d676e0..78a69b0a 100644
--- a/content/documentation/contributing.md
+++ b/content/doc/contributing.md
@@ -4,13 +4,11 @@ category = "concepts"
showChildren=true
[menu.main]
name = "How To Contribute"
- weight = 1
- identifier = "contributing"
- parent = "Getting Started"
+ weight = 2
+ identifier = "doc-contributing"
+ parent = "Getting Started With NATS"
+++
-# Contributing to NATS
-
## Introduction
Do you want to contribute to NATS? Awesome! We’d love your help. To make it easier for you to contribute, we’ve provided some guidelines below to ensure that you (the contributor) know what we (the project maintainers) look for in terms of content as well as the criteria and procedures we use when reviewing your submissions.
@@ -25,10 +23,10 @@ When discussing GitHub procedures, we’ll use the term “committers” to refe
NATS is designed with four goals in mind:
- * Performance - achieve the highest message throughput and lowest latency possible
- * Stability - "always on". Nothing we put in NATS should cause it to crash, and NATS should guard itself against unruly client behavior that might compromise performance or availability for all clients.
- * Simplicity - a compact, simple, and easily mastered API that requires no knowledge about the implementation of the broker (`gnatsd`), and a broker that is lightweight, requiring minimal configuration, system resources and external dependencies.
- * Security - NATS supports basic security features: authentication, authorization and encryption (TLS)
+- Performance - achieve the highest message throughput and lowest latency possible
+- Stability - "always on". Nothing we put in NATS should cause it to crash, and NATS should guard itself against unruly client behavior that might compromise performance or availability for all clients.
+- Simplicity - a compact, simple, and easily mastered API that requires no knowledge about the implementation of the broker (`gnatsd`), and a broker that is lightweight, requiring minimal configuration, system resources and external dependencies.
+- Security - NATS supports basic security features: authentication, authorization and encryption (TLS)
## Talking to Other NATS Users and Contributors
@@ -95,11 +93,11 @@ To contribute changes, simply fork/clone the project, find the appropriate markd
We will apply common-sense criteria to the review of these documentation-related pull requests:
- * Correct grammar and spelling
- * Correctness of content
- * Relevance to subject matter
- * Duplication of existing content
-
+- Correct grammar and spelling
+- Correctness of content
+- Relevance to subject matter
+- Duplication of existing content
+
## Contributing By Testing
We write tests for every new feature and update them for every change.
@@ -110,51 +108,48 @@ Please test our releases in your environment and report any issues you run into
## Contributing Code
-## Preparing to Contribute Code Changes
-
### Choosing What To Contribute
NATS is a small but ambitious project with a similarly small dedicated core team. Review of any proposed change can be a very time consuming task, and there will be times when our available bandwidth for PR review is limited. Therefore everyone benefits if submissions are useful, clear, easy to evaluate, and already pass basic checks.
-If you are eager to contribute, but you're just not sure *what* to contribute, please check the GitHub Issues for the relevant project for open issues labeled [**help wanted**](https://github.com/issues?utf8=%E2%9C%93&q=org%3Anats-io+is%3Aopen+is%3Aissue+label%3A%22help+wanted%22). You may also ask in the [NATS Google group](https://groups.google.com/forum/#!forum/natsio) or the [NATS Slack team](http://natsio.slack.com). If you need to join, you can request an invitation to join via the Slack icon on our [Community Page](http://nats.io/community/).
+If you are eager to contribute, but you're just not sure-what* to contribute, please check the GitHub Issues for the relevant project for open issues labeled [**help wanted**](https://github.com/issues?utf8=%E2%9C%93&q=org%3Anats-io+is%3Aopen+is%3Aissue+label%3A%22help+wanted%22). You may also ask in the [NATS Google group](https://groups.google.com/forum/#!forum/natsio) or the [NATS Slack team](http://natsio.slack.com). If you need to join, you can request an invitation to join via the Slack icon on our [Community Page](http://nats.io/community/).
Before you get started, please consider whether the proposed change is likely to be relevant, new and actionable.
- * Is it clear that code must change? In other words, has a clear problem or change been identified? As with most software projects, many issues that new users run into are rooted more in their understanding of how to use the software than in actual defects or limitations of the software.
- * Check to see if there is history behind your proposal. Search the project's GitHub Issues and the [NATS Google group](https://groups.google.com/forum/#!forum/natsio) for relevant discussions. Often, the problem has been discussed before, with a resolution that doesn’t require a code change, or recording what kinds of changes will not be accepted as a resolution. If you don't find anything in either of those places, ask in the #general channel of the [NATS Slack team](http://natsio.slack.com) to see if anyone has anything to say.
- * If you’re considering modifying code that is in the data path (i.e. central to message flow in the server or in the client), have you taken time to understand why the current implementation was chosen? Fixing a typo is straightforward, but the core logic and algorithms of the NATS server (`gnatsd`) are the result of a significant amount of combined experience developing and supporting messaging solutions. That doesn't mean they're flawless, but please know that changes in this area will be scrutinized closely against performance and stability concerns. We suggest that If you're uncertain why the existing code is written in a particular way, or what the impact of your proposed change(s) might be, ask questions of the NATS team via Slack or the Google group.
+- Is it clear that code must change? In other words, has a clear problem or change been identified? As with most software projects, many issues that new users run into are rooted more in their understanding of how to use the software than in actual defects or limitations of the software.
+- Check to see if there is history behind your proposal. Search the project's GitHub Issues and the [NATS Google group](https://groups.google.com/forum/#!forum/natsio) for relevant discussions. Often, the problem has been discussed before, with a resolution that doesn’t require a code change, or recording what kinds of changes will not be accepted as a resolution. If you don't find anything in either of those places, ask in the #general channel of the [NATS Slack team](http://natsio.slack.com) to see if anyone has anything to say.
+- If you’re considering modifying code that is in the data path (i.e. central to message flow in the server or in the client), have you taken time to understand why the current implementation was chosen? Fixing a typo is straightforward, but the core logic and algorithms of the NATS server (`gnatsd`) are the result of a significant amount of combined experience developing and supporting messaging solutions. That doesn't mean they're flawless, but please know that changes in this area will be scrutinized closely against performance and stability concerns. We suggest that If you're uncertain why the existing code is written in a particular way, or what the impact of your proposed change(s) might be, ask questions of the NATS team via Slack or the Google group.
### Code Review Criteria
-Knowing what's likely to be accepted or rejected and *why* is a key consideration in deciding whether and what to contribute. The criteria below are things we think about and look for in any proposed change. We have Performance, Stability, Simplicity, and Security in mind at all times.
+Knowing what's likely to be accepted or rejected and-why* is a key consideration in deciding whether and what to contribute. The criteria below are things we think about and look for in any proposed change. We have Performance, Stability, Simplicity, and Security in mind at all times.
Simply put, changes that have many or large positives, and few negative effects or risks, are much more likely to be merged, and merged quickly. Risky and less valuable changes are very unlikely to be merged, and may be rejected outright rather than receive iterations of review.
#### Pluses
- * Fixes the root cause of a bug in existing functionality
- * Adds functionality or fixes a problem needed by a large number of users
- * Simple, targeted
- * Maintains or improves consistency across supported API languages
- * Easily tested; has tests
- * Reduces complexity and lines of code
- * Change has already been discussed and is known to the committers
+- Fixes the root cause of a bug in existing functionality
+- Adds functionality or fixes a problem needed by a large number of users
+- Simple, targeted
+- Maintains or improves consistency across supported API languages
+- Easily tested; has tests
+- Reduces complexity and lines of code
+- Change has already been discussed and is known to the committers
-
#### Minuses
- * Non-optional new functionality that negatively affects performance
- * Band-aids a symptom of a bug only
- * Introduces complex new functionality, especially an API that needs to be supported
- * Adds complexity that only helps a niche use case
- * Adds user-space functionality that does not need to be maintained as part of NATS
- * Changes a public API or semantics (rarely allowed)
- * Adds large dependencies
- * Changes versions of existing dependencies
- * Adds a large amount of code
- * Is not modular/targeted -- makes lots of modifications in one “big bang” change
- * Breaks existing tests (implying your change is not backwards compatible)
- * Code coverage decreases (implying you didn’t add sufficient tests for new/changed code)
+- Non-optional new functionality that negatively affects performance
+- Band-aids a symptom of a bug only
+- Introduces complex new functionality, especially an API that needs to be supported
+- Adds complexity that only helps a niche use case
+- Adds user-space functionality that does not need to be maintained as part of NATS
+- Changes a public API or semantics (rarely allowed)
+- Adds large dependencies
+- Changes versions of existing dependencies
+- Adds a large amount of code
+- Is not modular/targeted -- makes lots of modifications in one “big bang” change
+- Breaks existing tests (implying your change is not backwards compatible)
+- Code coverage decreases (implying you didn’t add sufficient tests for new/changed code)
## Contributing Code Changes and Proposing New Features
@@ -170,18 +165,18 @@ For swift consideration, we suggest that you search to see if someone has alread
If you have a unique issue, please be as descriptive as possible:
- * Use a short, descriptive title that gives a clue what the Issue is about
- * Describe (if applicable) the environment you're running on (OS, hardware, VM, Docker, etc)
- * Describe what version (if applicable) of `gnatsd` or relevant client libraries you're using
- * Give a detailed description of the problem and why you view it as a problem.
- * Whenever possible, **please** include a [Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve)
- * If relevant, include or attach screenshots
- * If relevant, include log output of `gnatsd` (obtained by running `gnatsd -DV`. Trimming the log output to the relevant time period is always appreciated.
- * If you have a unique issue you deem may include a vulnerability that would affect a broad user base in a highly negative or impactful way, you may log such issues privately to the NATS team via email , private direct message on [NATS Slack](https://natsio.slack.com) or private direct message on [NATS Twitter](https://twitter.com/nats_io).
-
+- Use a short, descriptive title that gives a clue what the Issue is about
+- Describe (if applicable) the environment you're running on (OS, hardware, VM, Docker, etc)
+- Describe what version (if applicable) of `gnatsd` or relevant client libraries you're using
+- Give a detailed description of the problem and why you view it as a problem.
+- Whenever possible,-*please** include a [Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve)
+- If relevant, include or attach screenshots
+- If relevant, include log output of `gnatsd` (obtained by running `gnatsd -DV`. Trimming the log output to the relevant time period is always appreciated.
+- If you have a unique issue you deem may include a vulnerability that would affect a broad user base in a highly negative or impactful way, you may log such issues privately to the NATS team via email , private direct message on [NATS Slack](https://natsio.slack.com) or private direct message on [NATS Twitter](https://twitter.com/nats_io).
+
#### Change Proposals and Feature Requests
-When submitting a new Issue for a change proposal or feature request, tell us *why* the change is necessary. State the use case (e.g. "As a _________, I need to __________") *without* assuming any particular implementation. Stating only that "NATS should... (do some new technical thing)" is about as useful as stating that your car should be a tractor :) Help us understand the real problem you're trying to solve, in terms of the problem itself.
+When submitting a new Issue for a change proposal or feature request, tell us-why* the change is necessary. State the use case (e.g. "As a _________, I need to __________") *without* assuming any particular implementation. Stating only that "NATS should... (do some new technical thing)" is about as useful as stating that your car should be a tractor :) Help us understand the real problem you're trying to solve, in terms of the problem itself.
### Pull Requests
@@ -194,36 +189,38 @@ We follow standard GitHub procedures for creating and processing pull requests.
3. Consider whether documentation or tests need to be added or updated as part of the change, and add them as needed.
4. Run all tests to verify that the code still compiles, passes tests, and passes style checks. If style checks fail, review the relevant Code Style Guide in the project you're working in. It’s also advisable to ensure that any checks found in `.travis.yml` run successfully on your local system, when possible. These often include code formatting and static analysis checks that may cause CI tests to fail.
5. Open a pull request against the `master` branch of the relevant project (e.g. `nats-io/gnatsd`). (Only in special cases would the PR be opened against other branches.)
- * The PR title should be of the form `[ADDED | FIXED | CHANGED | UPDATED] `
- * `ADDED` - a new feature or content was added
- * `FIXED` - a defect in existing behavior was resolved
- * `CHANGED` - existing non-broken behavior was changed
- * `UPDATED` - new behavior was added to an existing behavior (could also be considered `CHANGED`, but please think about which tag you use)
- * If the pull request is still a work in progress, and so is not ready to be merged, but needs to be pushed to GitHub to facilitate review, then prepend `[WIP]` to the PR title, and if needed ping (`/cc @user`) the relevant reviewer(s) for advice, or contact them via Slack.
- * Consider identifying committers or other contributors who have worked on the code being changed. Find the file(s) in Github and click “Blame” to see a line-by-line annotation of who changed the code last. You can add @username in the PR description to ping them immediately.
- * Please state that the contribution is your original work and that you license the work to the project under the project’s open source license.
+ - The PR title should be of the form `[ADDED | FIXED | CHANGED | UPDATED] `
+ - `ADDED` - a new feature or content was added
+ - `FIXED` - a defect in existing behavior was resolved
+ - `CHANGED` - existing non-broken behavior was changed
+ - `UPDATED` - new behavior was added to an existing behavior (could also be considered `CHANGED`, but please think about which tag you use)
+ - If the pull request is still a work in progress, and so is not ready to be merged, but needs to be pushed to GitHub to facilitate review, then prepend `[WIP]` to the PR title, and if needed ping (`/cc @user`) the relevant reviewer(s) for advice, or contact them via Slack.
+ - Consider identifying committers or other contributors who have worked on the code being changed. Find the file(s) in Github and click “Blame” to see a line-by-line annotation of who changed the code last. You can add @username in the PR description to ping them immediately.
+ - Please state that the contribution is your original work and that you license the work to the project under the project’s open source license.
6. Travis CI will automatically build and test your changes. This should be a relatively quick process, and will report any errors as well as code coverage changes within a few minutes.
7. Watch for the results, and investigate and fix failures promptly. PRs with failing tests will not be reviewed or accepted.
- * Fixes can simply be pushed to the same branch from which you opened your pull request
- * Travis CI will automatically re-test when new commits are pushed
- * If the tests failed for reasons unrelated to the change (e.g. timing issues in Travis), the test can usually be re-run in Travis. Ask a committer if you need a test restarted, or if there are any other test failures that you believe are not related to your change(s).
- * Sometimes, other changes will be merged which conflict with your pull request’s changes. The PR can’t be merged until the conflict is resolved. This can typically be resolved with `git pull --rebase origin master` and resolving the conflicts by hand, then pushing the result to your branch.
- * Try to be responsive to the discussion rather than let days pass between replies.
+ - Fixes can simply be pushed to the same branch from which you opened your pull request
+ - Travis CI will automatically re-test when new commits are pushed
+ - If the tests failed for reasons unrelated to the change (e.g. timing issues in Travis), the test can usually be re-run in Travis. Ask a committer if you need a test restarted, or if there are any other test failures that you believe are not related to your change(s).
+ - Sometimes, other changes will be merged which conflict with your pull request’s changes. The PR can’t be merged until the conflict is resolved. This can typically be resolved with `git pull --rebase origin master` and resolving the conflicts by hand, then pushing the result to your branch.
+ - Try to be responsive to the discussion rather than let days pass between replies.
8. Squash your changes to a single commit as described [here](http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html).
- 8. Remember to remove `[WIP]` from your PR title once it is ready for submission, otherwise it will be ignored.
+ 9. Remember to remove `[WIP]` from your PR title once it is ready for submission, otherwise it will be ignored.
### Review Process
- * The review process will begin only when all CI tests are green.
- * Other reviewers, including committers, may comment on the changes and suggest modifications. Changes can be added by simply pushing more commits to the same branch.
- * Lively, polite, rapid technical debate is encouraged from everyone in the community. The outcome may be a rejection of the entire change.
- * Reviewers can indicate that a change looks suitable for merging with a comment such as: “I think this patch/pull/change looks good”, or, more succinctly, "LGTM" (looks good to me).
- * Generally we require LGTMs by at least two committers in order to approve a change for merge. There may be cases where this varies depending on size/scope/complexity of the change.
- * Sometimes, other changes will be merged which conflict with your pull request’s changes. The PR can’t be merged until the conflict is resolved. This can typically be resolved with `git pull --rebase origin master` and resolving the conflicts by hand, then pushing the result to your branch.
+
+- The review process will begin only when all CI tests are green.
+- Other reviewers, including committers, may comment on the changes and suggest modifications. Changes can be added by simply pushing more commits to the same branch.
+- Lively, polite, rapid technical debate is encouraged from everyone in the community. The outcome may be a rejection of the entire change.
+- Reviewers can indicate that a change looks suitable for merging with a comment such as: “I think this patch/pull/change looks good”, or, more succinctly, "LGTM" (looks good to me).
+- Generally we require LGTMs by at least two committers in order to approve a change for merge. There may be cases where this varies depending on size/scope/complexity of the change.
+- Sometimes, other changes will be merged which conflict with your pull request’s changes. The PR can’t be merged until the conflict is resolved. This can typically be resolved with `git pull --rebase origin master` and resolving the conflicts by hand, then pushing the result to your branch.
### Closing Your Pull Request
- * If accepted, your pull request will be automatically closed once the change is merged into `master`
- * If your pull request is rejected, the committers will close your PR.
- * If committers have requested changes or further information from you, and you do not respond within a reasonable timeframe, your PR may be closed at our discretion.
+
+- If accepted, your pull request will be automatically closed once the change is merged into `master`
+- If your pull request is rejected, the committers will close your PR.
+- If committers have requested changes or further information from you, and you do not respond within a reasonable timeframe, your PR may be closed at our discretion.
## Code Style Guide
@@ -235,5 +232,3 @@ NATS follows widely-adopted standards for code formatting and style in each impl
- Sir Isaac Newton
In preparing this guide, we gratefully borrowed ideas and words from the contribution guidelines of other popular open-source projects such as Apache Spark, Redis, and Docker. We thank them for inspiring us.
-
-
diff --git a/content/documentation/faq.md b/content/doc/faq.md
similarity index 89%
rename from content/documentation/faq.md
rename to content/doc/faq.md
index 6e1c975e..8bc4fc50 100644
--- a/content/documentation/faq.md
+++ b/content/doc/faq.md
@@ -1,16 +1,13 @@
+++
-title = "FAQ"
+title = "NATS Frequently Asked Questions"
category = "concepts"
-showChildren=true
[menu.main]
name = "FAQ"
- weight = 0
- identifier = "faq"
- parent = "Getting Started"
+ weight = 3
+ identifier = "doc-faq"
+ parent = "Getting Started With NATS"
+++
-# NATS Frequently Asked Questions
-
### General
* [What is NATS?] (#NATS)
@@ -19,6 +16,7 @@ showChildren=true
* [What clients does NATS support?] (#clients)
### Technical Questions
+
* [What is the difference between Request() and Publish()?] (#reqvspub)
* [Can multiple subscribers receive a Request?] (#multresponse)
* [How can I monitor my NATS cluster?] (#monitor)
@@ -35,10 +33,11 @@ showChildren=true
* [How do I create subjects?] (#createsubjects)
## General
+
### What is NATS?
NATS is an open source, lightweight, high-performance cloud native infrastructure messaging system. It implements a highly scalable and elegant publish-subscribe (pub/sub) distribution model. The performant nature of NATS make it an ideal base for building modern, reliable, scalable cloud native distributed systems.
-NATS is offered in two interoperable modules: the core NATS platform (referred to simply as "NATS" throughout this site), and [NATS Streaming](/documentation/streaming/nats-streaming-intro/), an event streaming service that can be employed to add event streaming, delivery guarantees, and historical data replay to NATS.
+NATS is offered in two interoperable modules: the core NATS platform (referred to simply as "NATS" throughout this site), and [NATS Streaming](/doc/streaming/nats-streaming-intro/), an event streaming service that can be employed to add event streaming, delivery guarantees, and historical data replay to NATS.
NATS was created by Derek Collison, who has over 20 years designing, building, and using publish-subscribe messaging systems. NATS is maintained by an amazing OpenSource Ecosystem, find more at [GitHub](https://www.github.com/nats-io).
@@ -80,7 +79,7 @@ There are several options available, thanks to the active NATS community:
* [nats-mon](https://github.com/repejota/nats-mon) is a monitoring tool developed by Raül Pérez and Adrià Cidre.
-A more detailed overview of monitoring is available under [Server Monitoring](/documentation/server/gnatsd-monitoring/).
+A more detailed overview of monitoring is available under [Server Monitoring](/doc/managing_the_server/monitoring/).
### Does NATS do queuing? Does NATS do load balancing?
@@ -92,7 +91,7 @@ This form of distributed queueing is done in real time, and messages are not per
NATS maintains and constantly updates the interest graph (subjects and their subscribers) in real time. Do not think of it as a "directory" that is aggregated over time. The interest graph dynamic, and will change constantly as publishers and subscribers come and go.
-If you are determined to gather this information, it can be indirectly derived at any instant in time by polling the monitoring endpoint for /connz and /routez. See [Server Monitoring](/documentation/server/gnatsd-monitoring/) for more information.
+If you are determined to gather this information, it can be indirectly derived at any instant in time by polling the monitoring endpoint for /connz and /routez. See [Server Monitoring](/doc/managing_the_server/monitoring/) for more information.
### Does NATS support subject wildcards?
@@ -126,15 +125,15 @@ No. As of `gnatsd` v0.8.0, there is no hard limit on the maximum number of subje
### Does NATS guarantee message delivery?
-NATS is offered as two components: the basic platform (referred to simply as "NATS") and [NATS Streaming](/documentation/streaming/nats-streaming-intro/), which is a data streaming service based on NATS.
+NATS is offered as two components: the basic platform (referred to simply as "NATS") and [NATS Streaming](/doc/streaming/nats-streaming-intro/), which is a data streaming service based on NATS.
- **NATS** implements what is commonly referred to as "at-most-once" delivery. This means that messages are guaranteed to arrive intact, in order from a given publisher, but not across different publishers. NATS does everything required to remain on and provide a dial-tone. However, if a subscriber is problematic or goes offline it will not receive messages, as the basic NATS platform is a simple pub-sub transport system that offers only TCP reliability.
-- **[NATS Streaming](/documentation/streaming/nats-streaming-intro/)** offers _at-least-once_ delivery guarantees by implementing publish and delivery acknowledgements, and persisting messages to memory or a secondary store until messages have been successfully delivered, or until resource limits or other administrator-defined limits have been reached.
+- **[NATS Streaming](/doc/streaming/nats-streaming-intro/)** offers _at-least-once_ delivery guarantees by implementing publish and delivery acknowledgements, and persisting messages to memory or a secondary store until messages have been successfully delivered, or until resource limits or other administrator-defined limits have been reached.
### Does NATS support replay/redelivery of historical data?
-Yes, historical data may be persisted to memory or secondary storage and replayed using [NATS Streaming](/documentation/streaming/nats-streaming-intro/), an event streaming service based on (and compatible with) NATS.
+Yes, historical data may be persisted to memory or secondary storage and replayed using [NATS Streaming](/doc/streaming/nats-streaming-intro/), an event streaming service based on (and compatible with) NATS.
### How do I gracefully shut down an asynchronous subscriber?
diff --git a/content/documentation/internals/nats-guide.md b/content/doc/internals/nats-client-dev.md
similarity index 69%
rename from content/documentation/internals/nats-guide.md
rename to content/doc/internals/nats-client-dev.md
index 74bf4a38..e697180c 100644
--- a/content/documentation/internals/nats-guide.md
+++ b/content/doc/internals/nats-client-dev.md
@@ -5,8 +5,8 @@ category = "internals"
[menu.main]
name = "Client Development"
weight = 3
- identifier = "internals-nats-guide"
- parent = "Internals"
+ identifier = "doc-client-dev"
+ parent = "NATS Internals"
+++
# NATS Client Development Guide
@@ -25,11 +25,21 @@ This guide provides you with considerations for developing NATS clients, includi
- Error handling, disconnecting and reconnecting
- Cluster support
-Check out the tutorial [Develop Go Clients for NATS](/documentation/tutorials/nats-client-dev/) for a step-by-step implementation of a simple Go client for NATS.
+Probably the best way to learn about implementing a client is to look at one of the client's maintained by the Synadia team. These clients are generally full featured, so if you can use them, that is even better, but if you have to write a client these may go beyond your needs while still capturing many of the design considerations discussed here.
+
+- [go](https://github.com/nats-io/go-nats)
+- [node](https://github.com/nats-io/node-nats)
+- [typescript](https://github.com/nats-io/ts-nats)
+- [python2](https://github.com/nats-io/python-nats)
+- [python asyncio](https://github.com/nats-io/asyncio-nats)
+- [java](https://github.com/nats-io/java-nats)
+- [c#](https://github.com/nats-io/csharp-nats)
+- [ruby](https://github.com/nats-io/ruby-nats)
+- [c](https://github.com/nats-io/cnats)
## Client connection options
-Clients can connect in authenticated or unauthenticated mode, as well as verbose mode which enables acknowledgements. See the [protocol documentation](/documentation/internals/nats-protocol/#CONNECT) for details.
+Clients can connect in authenticated or unauthenticated mode, as well as verbose mode which enables acknowledgements. See the [protocol documentation](/doc/internals/nats-protocol/#CONNECT) for details.
## Client authorization
@@ -49,9 +59,7 @@ nats.Connect("nats://foo:bar@localhost:4222")
## Verbose mode
-When 'verbose' is enabled (via the `CONNECT` message), the NATS server will return `+OK` to acknowledge receipt of a valid protocol message.
-The NATS server automatically runs in verbose mode.
-Most client implementations disable verbose mode (set it to `false` in the `CONNECT` message) for performance reasons.
+When 'verbose' is enabled (via the `CONNECT` message), the NATS server will return `+OK` to acknowledge receipt of a valid protocol message. The NATS server automatically runs in verbose mode. Most client implementations disable verbose mode (set it to `false` in the `CONNECT` message) for performance reasons.
## Pedantic mode
@@ -63,9 +71,9 @@ NATS implements auto-pruning. When a client connects to the server, the server e
## Parsing the protocol
-NATS provides a text-based message format. The text-based [protocol](/documentation/internals/nats-protocol/) makes it easy to implement NATS clients. The key consideration is deciding on a parsing stategy.
+NATS provides a text-based message format. The text-based [protocol](/doc/internals/nats-protocol/) makes it easy to implement NATS clients. The key consideration is deciding on a parsing strategy.
-The NATS server parser is a zero allocation byte parser. Off the wire, a NATS message is simply a slice of bytes. Across the wire the message is transported as an immutable string over a TCP connection. It is up to the client to implement logic to parse the message.
+The NATS server implements a [zero allocation byte parser](https://youtu.be/ylRKac5kSOk?t=10m46s) that is fast and efficient. Off the wire, a NATS message is simply a slice of bytes. Across the wire the message is transported as an immutable string over a TCP connection. It is up to the client to implement logic to parse the message.
The NATS message structure includes the Subject string, an optional Reply string, and an optional Data field that is a byte array. The type `Msg` is a structure used by Subscribers and PublishMsg().
@@ -92,7 +100,7 @@ When you make a subscription to the server, you need to store and dispatch callb
On the client side, you need a hash map for this data structure. The hash map will be storing the callback that maps the subscription ID to the subscription.
-The key of the hash map is the subscription ID. The key is used to look up the callback in the hashmap. When you process the NATS message off the wire, you pass the parameters subject, reply subject, and the payload to the callback handler, which does its work.
+The key of the hash map is the subscription ID. The key is used to look up the callback in the hash map. When you process the NATS message off the wire, you pass the parameters subject, reply subject, and the payload to the callback handler, which does its work.
Thus, you must store the mapping of subscription ID to the callback. Inside the subscription you have the callback.
diff --git a/content/documentation/internals/nats-protocol-demo.md b/content/doc/internals/nats-protocol-demo.md
similarity index 87%
rename from content/documentation/internals/nats-protocol-demo.md
rename to content/doc/internals/nats-protocol-demo.md
index c3af2d27..f36be194 100644
--- a/content/documentation/internals/nats-protocol-demo.md
+++ b/content/doc/internals/nats-protocol-demo.md
@@ -1,19 +1,17 @@
+++
date = "2015-09-27"
-title = "Protocol Demo"
+title = "NATS Protocol Demo"
category = "internals"
[menu.main]
name = "Protocol Demo"
weight = 2
- identifier = "internals-nats-protocol-demo"
- parent = "Internals"
+ identifier = "doc-protocol-demo"
+ parent = "NATS Internals"
+++
-# NATS Protocol Demo
+The virtues of the NATS protocol manifest quickly when you experience how easy it is to use NATS. Because the NATS protocol is text-based, you can use NATS across virtually any platform or language. In the following demo we use [Telnet](https://en.wikipedia.org/wiki/Telnet).
-The virtues of the NATS protocol manifest when you experience how easy it is to use NATS. Because the NATS protocol is text-based, you can use NATS across virtually any platform or language. In the following demo we use [Telnet](https://en.wikipedia.org/wiki/Telnet).
-
-On the wire you can publish and subscribe using a simple [set of protocol commands](/documentation/internals/nats-protocol/).
+On the wire you can publish and subscribe using a simple [set of protocol commands](/doc/internals/nats-protocol/).
## Instructions
diff --git a/content/documentation/internals/nats-protocol.md b/content/doc/internals/nats-protocol.md
similarity index 67%
rename from content/documentation/internals/nats-protocol.md
rename to content/doc/internals/nats-protocol.md
index fb6bf2fa..902fae12 100644
--- a/content/documentation/internals/nats-protocol.md
+++ b/content/doc/internals/nats-protocol.md
@@ -3,21 +3,25 @@ date = "2018-06-12"
title = "NATS Client Protocol"
category = "internals"
[menu.main]
- name = "NATS Client Protocol"
+ name = "Client Protocol"
weight = 1
- identifier = "internals-nats-protocol"
- parent = "Internals"
+ identifier = "doc-client-protocol"
+ parent = "NATS Internals"
+++
-# NATS Client protocol
+The wire protocol used to communicate between the NATS server and clients is a simple, text-based publish/subscribe style protocol. Clients connect to and communicate with `gnatsd` (the NATS server) through a regular TCP/IP socket using a small set of protocol operations that are terminated by a new line.
-The NATS wire protocol is a simple, text-based publish/subscribe style protocol. Clients connect to and communicate with `gnatsd` (the NATS server) through a regular TCP/IP socket using a small set of protocol operations that are terminated by newline.
-
-Unlike traditional messaging systems that use a binary message format that require an API to consume, the text-based NATS protocol makes it easy to implement clients in a wide variety of programming and scripting languages.
+Unlike traditional messaging systems that use a binary message format that require an API to consume, the text-based NATS protocol makes it easy to implement clients in a wide variety of programming and scripting languages. In fact, refer to the topic [NATS Protocol Demo](/doc/internals/nats-protocol-demo/) to play with the NATS protocol for yourself using telnet.
The NATS server implements a [zero allocation byte parser](https://youtu.be/ylRKac5kSOk?t=10m46s) that is fast and efficient.
-## NATS Client protocol conventions
+## Protocol conventions
+
+**Control line w/Optional Content**: Each interaction between the client and server consists of a control, or protocol, line of text followed, optionally by message content. Most of the protocol messages don't require content, only `PUB` and `MSG` include payloads.
+
+**Field Delimiters**: The fields of NATS protocol messages are delimited by whitespace characters '` `' (space) or `\t` (tab). Multiple whitespace characters will be treated as a single field delimiter.
+
+**Newlines**: NATS uses `CR` followed by `LF` (`CR+LF`, `\r\n`, `0x0D0A`) to terminate protocol messages. This newline sequence is also used to mark the end of the message payload in a `PUB` or `MSG` protocol message.
**Subject names**: Subject names, including reply subject (INBOX) names, are case-sensitive and must be non-empty alphanumeric strings with no embedded whitespace, and optionally token-delimited using the dot character (`.`), e.g.:
@@ -25,30 +29,23 @@ The NATS server implements a [zero allocation byte parser](https://youtu.be/ylRK
`FOO. BAR`, `foo. .bar` and`foo..bar` are *not* valid subject names
+**Character Encoding**: Subject names should be ascii characters for maximum interoperability. Due to language constraints and performance, some clients may support UTF-8 subject names, as may the server. No guarantees of non-ASCII support are provided.
+
**Wildcards**: NATS supports the use of wildcards in subject subscriptions.
-- The asterisk character (`*`) matches any token at any level of the subject.
+- The asterisk character (`*`) matches a single token at any level of the subject.
- The greater than symbol (`>`), also known as the _full wildcard_, matches one or more tokens at the tail of a subject, and must be the last token. The wildcarded subject `foo.>` will match `foo.bar` or `foo.bar.baz.1`, but not `foo`.
-- Wildcards must be separate tokens (`foo.*.baz` or `foo.>` are syntactically valid; `foo*.bar`, `f*o.b*r` and `foo>` are not)
+- Wildcards must be a separate token (`foo.*.baz` or `foo.>` are syntactically valid; `foo*.bar`, `f*o.b*r` and `foo>` are not)
For example, the wildcard subscriptions `foo.*.quux` and `foo.>` both match `foo.bar.quux`, but only the latter matches `foo.bar.baz`. With the full wildcard,
-it is also possible to express interest in every subject that may exist in NATS: `sub > 1`.
+it is also possible to express interest in every subject that may exist in NATS: `sub > 1`, limited of course by authorization settings.
-**Field Delimiters**: The fields of NATS protocol messages are delimited by whitespace characters '` `' (space) or `\t` (tab).
-Multiple whitespace characters will be treated as a single field delimiter.
+## Protocol messages
-**Newlines**: Like other text-based protocols, NATS uses `CR` followed by `LF` (`CR+LF`, `\r\n`, `0x0D0A`) to terminate protocol messages.
-This newline sequence is also used to mark the beginning of the actual message payload in a `PUB` or `MSG` protocol message.
-
-
-## NATS Client protocol messages
-
-The following table briefly describes the NATS protocol messages.
-NATS protocol operation names are case insensitive, thus `SUB foo 1\r\n` and `sub foo 1\r\n` are equivalent.
+The following table briefly describes the NATS protocol messages. NATS protocol operation names are case insensitive, thus `SUB foo 1\r\n` and `sub foo 1\r\n` are equivalent.
Click the name to see more detailed information, including syntax:
-
| OP Name | Sent By | Description
| -------------------- |:-------------- |:--------------------------------------------
| [`INFO`](#INFO) | Server | Sent to client after initial TCP/IP connection
@@ -62,59 +59,63 @@ Click the name to see more detailed information, including syntax:
| [`+OK`](#OKERR) | Server | Acknowledges well-formed protocol message in `verbose` mode
| [`-ERR`](#OKERR) | Server | Indicates a protocol error. May cause client disconnect.
-
-
The following sections explain each protocol message.
## INFO
-### Syntax
+#### Description
-`INFO {["option_name":option_value],...}`
+As soon as the server accepts a connection from the client, it will send information about itself and the configuration and security requirements that are necessary for the client to successfully authenticate with the server and exchange messages.
-The valid options are as follows:
+When using the updated client protocol (see [`CONNECT`](#CONNECT) below), `INFO` messages can be sent anytime by the server. This means clients with that protocol level need to be able to asynchronously handle `INFO` messages.
-* `server_id`: The unique identifier of the NATS server
-* `version`: The version of the NATS server
-* `go`: The version of golang the NATS server was built with
-* `host`: The IP address of the NATS server host
-* `port`: The port number the NATS server is configured to listen on
-* `auth_required`: If this is set, then the client should try to authenticate upon connect.
-* `ssl_required`: If this is set, then the client must authenticate using SSL.
-* `max_payload`: Maximum payload size that the server will accept from the client.
-* `connect_urls` : An optional list of server urls that a client can connect to.
-* `proto`: An integer indicating the protocol version of the server. The server version 1.2.0 sets this to `1` to indicate that it supports the "Echo" feature.
-* `client_id`: An optional unsigned integer (64 bits) representing the internal client identifier in the server. This can be used to filter client connections in monitoring, correlate with error logs, etc...
+#### Syntax
-### Description
+`INFO {["option_name":option_value],...}`
-As soon as the server accepts a connection from the client, it will send information about itself and the configuration and security requirements that are necessary for the client to successfully authenticate with the server and exchange messages.
+The valid options are as follows:
-When using the updated client protocol (see `CONNECT` below), `INFO` messages can be sent anytime by the server. This means clients with that protocol level need to be able to asynchronously handle `INFO` messages.
+- `server_id`: The unique identifier of the NATS server
+- `version`: The version of the NATS server
+- `go`: The version of golang the NATS server was built with
+- `host`: The IP address used to start the NATS server, by default this will be `0.0.0.0` and can be configured with `-client_advertise host:port`
+- `port`: The port number the NATS server is configured to listen on
+- `max_payload`: Maximum payload size, in bytes, that the server will accept from the client.
+- `proto`: An integer indicating the protocol version of the server. The server version 1.2.0 sets this to `1` to indicate that it supports the "Echo" feature.
+- `client_id`: An optional unsigned integer (64 bits) representing the internal client identifier in the server. This can be used to filter client connections in monitoring, correlate with error logs, etc...
+- `auth_required`: If this is set, then the client should try to authenticate upon connect.
+- `tls_required`: If this is set, then the client must perform the TLS/1.2 handshake. Note, this used to be `ssl_required` and has been updated along with the protocol from SSL to TLS.
+- `tls_verify`: If this is set, the client must provide a valid certificate during the TLS handshake.
+- `connect_urls` : An optional list of server urls that a client can connect to.
+
+##### connect_urls
-#### connect_urls
The `connect_urls` field is a list of urls the server may send when a client first connects, and when there are changes to server cluster topology. This field is considered optional, and may be omitted based on server configuration and client protocol level.
When a NATS server cluster expands, an `INFO` message is sent to the client with an updated `connect_urls` list. This cloud-friendly feature asynchronously notifies a client of known servers, allowing it to connect to servers not originally configured.
The `connect_urls` will contain a list of strings with an IP and port, looking like this: ```"connect_urls":["10.0.0.184:4333","192.168.129.1:4333","192.168.192.1:4333"]```
-### Example
+#### Example
Below you can see a sample connection string from a telnet connection to the `demo.nats.io` site.
-```
-telnet demo.nats.io 4222
+```sh
+% telnet demo.nats.io 4222
Trying 107.170.221.32...
Connected to demo.nats.io.
Escape character is '^]'.
-INFO {"server_id":"1ec445b504f4edfb4cf7927c707dd717","version":"0.6.6","go":"go1.4.2","host":"0.0.0.0","port":4222,"auth_required":false,"ssl_required":false,"max_payload":1048576}
+INFO {"server_id":"Zk0GQ3JBSrg3oyxCRRlE09","version":"1.2.0","proto":1,"go":"go1.10.3","host":"0.0.0.0","port":4222,"max_payload":1048576,"client_id":2392}
```
## CONNECT
-### Syntax
+#### Description
+
+The `CONNECT` message is the client version of the `INFO` message. Once the client has established a TCP/IP socket connection with the NATS server, and an `INFO` message has been received from the server, the client may send a `CONNECT` message to the NATS server to provide more information about the current connection as well as security information.
+
+#### Syntax
`CONNECT {["option_name":option_value],...}`
@@ -122,8 +123,8 @@ The valid options are as follows:
* `verbose`: Turns on [`+OK`](#OKERR) protocol acknowledgements.
* `pedantic`: Turns on additional strict format checking, e.g. for properly formed subjects
-* `ssl_required`: Indicates whether the client requires an SSL connection.
-* `auth_token`: Client authorization token
+* `tls_required`: Indicates whether the client requires an SSL connection.
+* `auth_token`: Client authorization token (if `auth_required` is set)
* `user`: Connection username (if `auth_required` is set)
* `pass`: Connection password (if `auth_required` is set)
* `name`: Optional client name
@@ -132,10 +133,8 @@ The valid options are as follows:
* `protocol`: *optional int*. Sending `0` (or absent) indicates client supports original protocol. Sending `1` indicates that the client supports dynamic reconfiguration of cluster topology changes by asynchronously receiving `INFO` messages with known servers it can reconnect to.
* `echo`: Optional boolean. If set to `true`, the server (version 1.2.0+) will not send originating messages from this connection to its own subscriptions. Clients should set this to `true` only for server supporting this feature, which is when `proto` in the `INFO` protocol is set to at least `1`.
-### Description
-The `CONNECT` message is analogous to the `INFO` message. Once the client has established a TCP/IP socket connection with the NATS server, and an `INFO` message has been received from the server, the client may send a `CONNECT` message to the NATS server to provide more information about the current connection as well as security information.
+#### Example
-### Example
Here is an example from the default string of the Go client:
```
@@ -146,22 +145,24 @@ Most clients set `verbose` to `false` by default. This means that the server sho
## PUB
-### Syntax
+#### Description
+
+The `PUB` message publishes the message payload to the given subject name, optionally supplying a reply subject. If a reply subject is supplied, it will be delivered to eligible subscribers along with the supplied payload. Note that the payload itself is optional. To omit the payload, set the payload size to 0, but the second CRLF is still required.
+
+#### Syntax
+
`PUB [reply-to] <#bytes>\r\n[payload]\r\n`
where:
-* `subject`: The destination subject to publish to
-* `reply-to`: The reply inbox subject that subscribers can use to send a response back to the publisher/requestor
-* `#bytes`: The payload size in bytes
-* `payload`: The message payload data
-
-### Description
-The `PUB` message publishes the message payload to the given subject name, optionally supplying a reply subject. If a reply subject is supplied, it will be delivered to eligible subscribers along with the supplied payload. Note that the payload itself is optional. To omit the payload, set the payload size to 0.
+- `subject`: The destination subject to publish to
+- `reply-to`: The optional reply inbox subject that subscribers can use to send a response back to the publisher/requestor
+- `#bytes`: The payload size in bytes
+- `payload`: The message payload data
-### Example
+#### Example
-To publish the string message payload "Hello NATS!" to subject FOO:
+To publish the ASCII string message payload "Hello NATS!" to subject FOO:
`PUB FOO 11\r\nHello NATS!\r\n`
@@ -175,20 +176,21 @@ To publish an empty message to subject NOTIFY:
## SUB
-### Syntax
-`SUB [queue group] \r\n`
+#### Description
-where:
+`SUB` initiates a subscription to a subject, optionally joining a distributed queue group.
-* `subject`: The subject name to subscribe to
-* `queue group`: If specified, the subscriber will join this queue group
-* `sid`: A unique alphanumeric subscription ID
+#### Syntax
-### Description
+`SUB [queue group] \r\n`
-`SUB` initiates a subscription to a subject, optionally joining a distributed queue group.
+where:
+
+- `subject`: The subject name to subscribe to
+- `queue group`: If specified, the subscriber will join this queue group
+- `sid`: A unique alphanumeric subscription ID, generated by the client
-### Example
+#### Example
To subscribe to the subject `FOO` with the connection-unique subscription identifier (sid) `1`:
@@ -200,20 +202,20 @@ To subscribe the current connection to the subject `BAR` as part of distribution
## UNSUB
-### Syntax
+#### Description
+
+`UNSUB` unsubcribes the connection from the specified subject, or auto-unsubscribes after the specified number of messages has been received.
+
+#### Syntax
`UNSUB [max_msgs]`
where:
* `sid`: The unique alphanumeric subscription ID of the subject to unsubscribe from
-* `max_msgs`: Number of messages to wait for before automatically unsubscribing
-
-### Description
+* `max_msgs`: An optional number of messages to wait for before automatically unsubscribing
-`UNSUB` unsubcribes the connection from the specified subject, or auto-unsubscribes after the specified number of messages has been received.
-
-### Example
+#### Example
The following examples concern subject `FOO` which has been assigned sid `1`. To unsubscribe from `FOO`:
@@ -225,7 +227,11 @@ To auto-unsubscribe from `FOO` after 5 messages have been received:
## MSG
-### Syntax
+#### Description
+
+The `MSG` protocol message is used to deliver an application message to the client.
+
+#### Syntax
`MSG [reply-to] <#bytes>\r\n[payload]\r\n`
@@ -237,25 +243,35 @@ where:
* `#bytes`: Size of the payload in bytes
* `payload`: The message payload data
-### Description
+#### Example
-The `MSG` protocol message delivers a message to the client.
-
-### Example
-
-The following message delivers a message from subject `FOO.BAR`:
+The following message delivers an application message from subject `FOO.BAR`:
`MSG FOO.BAR 9 11\r\nHello World\r\n`
-Deliver the same message along with a reply inbox:
+To deliver the same message along with a reply inbox:
`MSG FOO.BAR 9 INBOX.34 11\r\nHello World\r\n`
## PING/PONG
-### Description
+#### Description
+
+`PING` and `PONG` implement a simple keep-alive mechanism between client and server. Once a client establishes a connection to the NATS server, the server will continuously send `PING` messages to the client at a configurable interval. If the client fails to respond with a `PONG` message within the configured response interval, the server will terminate its connection. If your connection stays idle for too long, it is cut off.
+
+If the server sends a ping request, you can reply with a pong message to notify the server that you are still interested. You can also ping the server and will receive a pong reply. The ping/pong interval is configurable.
+
+The server uses normal traffic as a ping/pong proxy, so a client that has messages flowing may not receive a ping from the server.
+
+#### Syntax
+
+`PING\r\n`
-`PING` and `PONG` implement a simple keep-alive mechanism between client and server. Once a client establishes a connection to the NATS server, the server will continuously send `PING` messages to the client at a configurable interval. If the client fails to respond with a `PONG` message within the configured response interval, the server will terminate its connection. If your connection stays idle for too long, it is cut off:
+`PONG\r\n`
+
+#### Example
+
+The following example shows the demo server pinging the client and finally shutting it down.
```
telnet demo.nats.io 4222
@@ -263,22 +279,16 @@ telnet demo.nats.io 4222
Trying 107.170.221.32...
Connected to demo.nats.io.
Escape character is '^]'.
-INFO {"server_id":"ad29ea9cbb16f2865c177bbd4db446ca","version":"0.6.8","go":"go1.5.1","host":"0.0.0.0","port":4222,"auth_required":false,"ssl_required":false,"max_payload":1048576}
+INFO {"server_id":"Zk0GQ3JBSrg3oyxCRRlE09","version":"1.2.0","proto":1,"go":"go1.10.3","host":"0.0.0.0","port":4222,"max_payload":1048576,"client_id":2392}
PING
PING
-ERR 'Stale Connection'
Connection closed by foreign host.
```
-If the server sends a ping request, you can reply with a pong message to notify the server that you are still interested. You can also ping the server and will receive a pong reply. The ping/pong interval is configurable.
-
## +OK/ERR
-### Syntax
-
-`+OK`
-
-`-ERR `
+#### Description
When the `verbose` connection option is set to `true` (the default value), the server acknowledges each well-formed protocol message from the client with a `+OK` message. Most NATS clients set the `verbose` option to `false` using the [CONNECT](#CONNECT) message
@@ -286,6 +296,12 @@ The `-ERR` message is used by the server indicate a protocol, authorization, or
Handling of these errors usually has to be done asynchronously.
+#### Syntax
+
+`+OK`
+
+`-ERR `
+
Some protocol errors result in the server closing the connection. Upon recieving these errors, the connection is no longer valid and the client should clean up relevant resources. These errors include:
- `-ERR 'Unknown Protocol Operation'`: Unknown protocol error
@@ -296,7 +312,7 @@ Some protocol errors result in the server closing the connection. Upon recievin
- `-ERR 'Maximum Control Line Exceeded'`: Message destination subject and reply subject length exceeded the maximum control line value specified by the `max_control_line` server option. The default is 1024 bytes.
- `-ERR 'Parser Error'`: Cannot parse the protocol message sent by the client
- `-ERR 'Secure Connection - TLS Required'`: The server requires TLS and the client does not have TLS enabled.
-- `-ERR 'Stale Connection'`: PING/PONG interval expired.
+- `-ERR 'Stale Connection'`: The server hasn't received a message from the client, including a `PONG` in too long.
- `-ERR 'Maximum Connections Exceeded`': This error is sent by the server when creating a new connection and the server has exceeded the maximum number of connections specified by the `max_connections` server option. The default is 64k.
- `-ERR 'Slow Consumer'`: The server pending data size for the connection has reached the maximum size (default 10MB).
- `-ERR 'Maximum Payload Violation'`: Client attempted to publish a message with a payload size that exceeds the `max_payload` size configured on the server. This value is supplied to the client upon connection in the initial [`INFO`](#INFO) message. The client is expected to do proper accounting of byte size to be sent to the server in order to handle this error synchronously.
@@ -306,8 +322,3 @@ Protocol error messages where the connection remains open are listed below. The
- `-ERR 'Invalid Subject'`: Client sent a malformed subject (e.g. `sub foo. 90`)
- `-ERR 'Permissions Violation for Subscription to '`: The user specified in the [CONNECT](#CONNECT) message does not have permission to subscribe to the subject.
- `-ERR 'Permissions Violation for Publish to '`: The user specified in the [CONNECT](#CONNECT) message does not have permissions to publish to the subject.
-
-
-## Protocol demo
-
-Refer to the topic [NATS Protocol Demo](/documentation/internals/nats-protocol-demo/) to demo the NATS protocol for yourself.
diff --git a/content/documentation/internals/nats-server-protocol.md b/content/doc/internals/nats-server-protocol.md
similarity index 91%
rename from content/documentation/internals/nats-server-protocol.md
rename to content/doc/internals/nats-server-protocol.md
index cd815e0c..f06273d3 100644
--- a/content/documentation/internals/nats-server-protocol.md
+++ b/content/doc/internals/nats-server-protocol.md
@@ -3,15 +3,13 @@ date = "2018-06-12"
title = "NATS Cluster Protocol"
category = "internals"
[menu.main]
- name = "NATS Cluster Protocol"
- weight = 1
- identifier = "internals-nats-server-protocol"
- parent = "Internals"
+ name = "Cluster Protocol"
+ weight = 4
+ identifier = "doc-server-protocol"
+ parent = "NATS Internals"
+++
-# NATS Cluster protocol
-
-The NATS server clustering protocol describes the messages passed between NATS servers within a [cluster](/documentation/server/gnatsd-cluster/) to share subscription state, forward messages, and share cluster topology. It is a simple, text-based publish/subscribe style protocol. Servers communicate with each other through a regular TCP/IP socket using a small set of protocol operations that are terminated by newline.
+The NATS server clustering protocol describes the messages passed between NATS servers within a [cluster](/doc/managing_the_server/clustering/) to share subscription state, forward messages, and share cluster topology. It is a simple, text-based publish/subscribe style protocol. Servers communicate with each other through a regular TCP/IP socket using a small set of protocol operations that are terminated by newline.
The NATS server implements a [zero allocation byte parser](https://youtu.be/ylRKac5kSOk?t=10m46s) that is fast and efficient.
@@ -26,7 +24,6 @@ Multiple whitespace characters will be treated as a single field delimiter.
**Newlines**: Like other text-based protocols, NATS uses `CR` followed by `LF` (`CR+LF`, `\r\n`, `0x0D0A`) to terminate protocol messages. This newline sequence is also used to mark the beginning of the actual message payload in a `PUB` or `MSG` protocol message.
-
## NATS Cluster protocol messages
The following table briefly describes the NATS cluster protocol messages.
@@ -52,7 +49,15 @@ The following sections explain each protocol message.
## INFO
-### Syntax
+#### Description
+
+As soon as the server accepts a connection from another server, it will send information about itself and the configuration and security requirements that are necessary for the other server to successfully authenticate with the server and exchange messages.
+
+The connecting server also sends an `INFO` message. The accepting server will add an `ip` field containing the address and port of the connecting server, and forward the new server's `INFO` message to all servers it is routed to.
+
+Any servers in a cluster receiving an `INFO` message with an `ip` field will attempt to connect to the server at that address, unless already connected. This propagation of `INFO` messages on behalf of a connecting server provides automatic discovery of new servers joining a cluster.
+
+#### Syntax
`INFO {["option_name":option_value],...}`
@@ -64,28 +69,24 @@ The valid options are as follows:
* `host`: The host specified in the cluster parameter/options
* `port`: The port number specified in the cluster parameter/options
* `auth_required`: If this is set, then the server should try to authenticate upon connect.
-* `ssl_required`: If this is set, then the server must authenticate using SSL.
+* `tls_required`: If this is set, then the server must authenticate using TLS.
* `max_payload`: Maximum payload size that the server will accept.
* `connect_urls` : A list of server urls that a client can connect to.
* `ip`: Optional route connection address of a server, `nats-route://:`
-### Description
-
-As soon as the server accepts a connection from another server, it will send information about itself and the configuration and security requirements that are necessary for the other server to successfully authenticate with the server and exchange messages.
-
-The connecting server also sends an `INFO` message. The accepting server will add an `ip` field containing the address and port of the connecting server, and forward the new server's `INFO` message to all servers it is routed to.
-
-Any servers in a cluster receiving an `INFO` message with an `ip` field will attempt to connect to the server at that address, unless already connected. This propagation of `INFO` messages on behalf of a connecting server provides automatic discovery of new servers joining a cluster.
-
-### Example
+#### Example
Below is an example of an `INFO` string received by a NATS server, with the `ip` field.
-`INFO {"server_id":"KP19vTlB417XElnv8kKaC5","version":"0.9.4","go":"","host":"localhost","port":5222,"auth_required":false,"ssl_required":false,"tls_required":false,"tls_verify":false,"max_payload":1048576,"ip":"nats-route://127.0.0.1:5222/","connect_urls":["localhost:4222"]}`
+`INFO {"server_id":"KP19vTlB417XElnv8kKaC5","version":"0.9.4","go":"","host":"localhost","port":5222,"auth_required":false,"tls_required":false,"tls_verify":false,"max_payload":1048576,"ip":"nats-route://127.0.0.1:5222/","connect_urls":["localhost:4222"]}`
## CONNECT
-### Syntax
+#### Description
+
+The `CONNECT` message is analogous to the `INFO` message. Once the NATS server has established a TCP/IP socket connection with another server, and an `INFO` message has been received, the server will send a `CONNECT` message to provide more information about the current connection as well as security information.
+
+#### Syntax
`CONNECT {["option_name":option_value],...}`
@@ -101,11 +102,7 @@ The valid options are as follows:
* `lang`: The implementation language of the server (go).
* `version`: The version of the server.
-### Description
-
-The `CONNECT` message is analogous to the `INFO` message. Once the NATS server has established a TCP/IP socket connection with another server, and an `INFO` message has been received, the server will send a `CONNECT` message to provide more information about the current connection as well as security information.
-
-### Example
+#### Example
Here is an example from the default string from a server.
@@ -115,7 +112,10 @@ Servers should set `verbose` to `false` by default. This means that other routed
## PUB
-### Syntax
+#### Description
+The `PUB` message publishes the message payload to the given subject name, optionally supplying a reply subject, to another server. If a reply subject is supplied, it will be delivered to eligible subscribers along with the supplied payload. Note that the payload itself is optional. To omit the payload, set the payload size to 0.
+
+#### Syntax
`PUB [reply-to] <#bytes>\r\n[payload]\r\n`
@@ -126,10 +126,7 @@ where:
* `#bytes`: The payload size in bytes
* `payload`: The message payload data
-### Description
-The `PUB` message publishes the message payload to the given subject name, optionally supplying a reply subject, to another server. If a reply subject is supplied, it will be delivered to eligible subscribers along with the supplied payload. Note that the payload itself is optional. To omit the payload, set the payload size to 0.
-
-### Example
+#### Example
To publish the string message payload "Hello NATS!" to subject FOO:
@@ -145,7 +142,11 @@ To publish an empty message to subject NOTIFY:
## SUB
-### Syntax
+#### Description
+
+`SUB` initiates a subscription to a subject, optionally joining a distributed queue group.
+
+#### Syntax
**Basic Subscription**: `SUB RSID::\r\n`
@@ -158,11 +159,7 @@ where:
* `cid`: A 64bit unsigned integer representing the client connection
* `sid`: A unique alphanumeric subscription ID representing the server's subscription
-### Description
-
-`SUB` initiates a subscription to a subject, optionally joining a distributed queue group.
-
-### Example
+#### Example
To subscribe to the subject `FOO` with the local unique subject identifier of `1`, and the connection-unique subject identifier (sid) `1`:
@@ -174,7 +171,11 @@ To subscribe the current connection to the subject `BAR` as part of distribution
## UNSUB
-### Syntax
+#### Description
+
+`UNSUB` unsubcribes the connection from the specified subject, or auto-unsubscribes after the specified number of messages has been received. It is sent by a server when one of it's clients unsubscribes.
+
+#### Syntax
**Basic Subscription**: `UNSUB RSID:: [max_msgs]\r\n`
@@ -187,11 +188,7 @@ where:
* `cid`: A 64bit unsigned integer representing the client connection
* `sid`: A unique alphanumeric subscription ID representing the server's subscription
-### Description
-
-`UNSUB` unsubcribes the connection from the specified subject, or auto-unsubscribes after the specified number of messages has been received. It is sent by a server when one of it's clients unsubscribes.
-
-### Example
+#### Example
The following examples concern subject `FOO` which has been assigned an internal subscriber id of `5`, and a client sid of `1`. To unsubscribe from `FOO`:
@@ -203,7 +200,11 @@ To auto-unsubscribe from `FOO` after 5 messages have been received:
## MSG
-### Syntax
+#### Description
+
+The `MSG` protocol message delivers a message from another server.
+
+#### Syntax
`MSG [reply-to] <#bytes>\r\n[payload]\r\n`
@@ -215,11 +216,7 @@ where:
* `#bytes`: Size of the payload in bytes
* `payload`: The message payload data
-### Description
-
-The `MSG` protocol message delivers a message from another server.
-
-### Example
+#### Example
The following message delivers a message from subject `FOO.BAR`:
@@ -231,19 +228,20 @@ Deliver the same message along with a reply inbox:
## PING/PONG
-### Description
+#### Description
`PING` and `PONG` implement a simple keep-alive mechanism between servers. Once two servers establish a connection with each other, the NATS server will continuously send `PING` messages to other servers at a configurable interval. If another server fails to respond with a `PONG` message within the configured response interval, the server will terminate its connection. If your connection stays idle for too long, it is cut off.
If the another server sends a ping request, a server will reply with a pong message to notify the other server that it is still present.
-## +OK/ERR
+#### Syntax
-### Syntax
+`PING\r\n`
+`PONG\r\n`
-`+OK`
+## +OK/ERR
-`-ERR `
+#### Description
When the `verbose` connection option is set to `true` (the default value), the server acknowledges each well-formed protocol message with a `+OK` message. NATS servers set the `verbose` option to `false` using the [CONNECT](#CONNECT) message
@@ -251,6 +249,12 @@ The `-ERR` message is used by the server indicate a protocol, authorization, or
Handling of these errors usually has to be done asynchronously.
+#### Syntax
+
+`+OK`
+
+`-ERR `
+
Protocol error messages which close the connection:
- `-ERR 'Unknown Protocol Operation'`: Unknown protocol error
diff --git a/content/doc/managing_the_server/authentication.md b/content/doc/managing_the_server/authentication.md
new file mode 100644
index 00000000..bed1d2ce
--- /dev/null
+++ b/content/doc/managing_the_server/authentication.md
@@ -0,0 +1,121 @@
++++
+date = "2015-09-27"
+title = "NATS Server Authentication"
+description = ""
+category = "server"
+[menu.main]
+ name = "Authentication"
+ weight = 3
+ identifier = "doc-server-authentication"
+ parent = "Managing the Server"
++++
+
+You can enable authentication on the NATS server so that a client must authenticate its identity when connecting. The NATS server supports single user authentication via the command line or using a configuration file, and multi-user authentication via a configuration file. Single user authentication is truly single user. The server will accept one set of credentials and no other.
+
+## Command Line Options
+
+You can start the NATS server with single-user authentication enabled by passing in the required credentials on the command line. The following server authentication options are supported on the command line:
+
+ --user user User required for connections
+ --pass password Password required for connections
+ --auth token Authorization token required for connections
+
+Token is mutually exclusive from user and password, so only use one of those.
+
+For example:
+
+```sh
+gnatsd -DV --user foo --pass bar
+```
+
+will allow the user `foo` to log in with the password `bar`, but no other users to access the server.
+
+Using the command line with an authorization token:
+
+```sh
+gnatsd -DV -auth 'S3Cr3T0k3n!'
+```
+
+will allow clients with that token to connect, and no others.
+
+## Single User Configuration Options
+
+Single-user authentication can be configured in the configuration file:
+
+```ascii
+authorization {
+ user: derek
+ password: T0pS3cr3t
+ timeout: 1
+}
+```
+
+If the server is part of a cluster, you can set up single-user authentication for route connections as well:
+
+```ascii
+cluster {
+ authorization {
+ user: route_user
+ password: T0pS3cr3tT00!
+ timeout: 0.5
+ }
+}
+```
+
+Both of these configurations set a user and password as well as a connect timeout. The `auth` option can also be set to use tokens *instead of* user/password.
+
+## Multi-User Authentication
+
+Multi-user Authentication can only be set up in the configuration file. Users are defined in a list with user/password pairs.
+
+For example, to define two users `alice` and `bob`:
+
+```ascii
+authorization {
+ users = [
+ {user: alice, password: foo}
+ {user: bob, password: bar}
+ ]
+}
+```
+
+You can also use [variables](/doc/managing_the_server/configuration) to set user and password values. For example, here a password is declared as a variable named PASS and assigned to Joe.
+
+```ascii
+authorization {
+ PASS: abcdefghijklmnopqrstuvwxyz0123456789
+ users = [
+ {user: alice, password: foo}
+ {user: bob, password: bar}
+ {user: joe, password: $PASS}
+ ]
+}
+```
+
+The gnatsd source code includes a tool that can be used to bcrypt passwords for the config file:
+
+```sh
+> go run mkpasswd.go -p
+> password: password
+> bcrypt hash: $2a$11$1oJy/wZYNTxr9jNwMNwS3eUGhBpHT3On8CL9o7ey89mpgo88VG6ba
+```
+
+This allows you to store hashed passwords instead of plain text ones.
+
+## Client connection string
+
+To connect to the server as an authenticated client, you can pass in the credentials in the connection string.
+
+For example, user 'foo' with password 'bar':
+
+```sh
+nats://foo:bar@localhost:4222
+```
+
+Using token 'S3Cr3T0k3n!'
+
+```sh
+nats://S3Cr3T0k3n!@localhost:4222
+```
+
+or use other methods discussed in the [developer doc](/doc/writing_applications/secure_connection).
diff --git a/content/documentation/server/gnatsd-authorization.md b/content/doc/managing_the_server/authorization.md
similarity index 68%
rename from content/documentation/server/gnatsd-authorization.md
rename to content/doc/managing_the_server/authorization.md
index d4f05a8d..1478c2be 100644
--- a/content/documentation/server/gnatsd-authorization.md
+++ b/content/doc/managing_the_server/authorization.md
@@ -1,24 +1,21 @@
+++
-date = "2018-05-22"
-title = "Server Authorization"
+title = "NATS Server Authorization"
description = ""
category = "server"
[menu.main]
- name = "Server Authorization"
- weight = 3
- identifier = "server-gnatsd-authorization"
- parent = "Server"
+ name = "Authorization"
+ weight = 5
+ identifier = "doc-server-authorization"
+ parent = "Managing the Server"
+++
-# NATS Server Authorization
+The NATS server supports authorization using subject-level permissions on a per-user basis. Permission-based authorization is available with [multi-user authentication](/doc/managing_the_server/authentication/).
-The NATS server supports authorization using subject-level permissions on a per-user basis. Permission-based authorization is available with [multi-user authentication](/documentation/server/gnatsd-authentication/).
-
-Each permission grant is an object with two fields: what subject(s) the authenticated user can publish to, and what subject(s) the authenticated user can subscribe to. The parser is generous at understanding what the intent is, so both arrays and singletons are processed. Subjects themselves can contain wildcards. Permissions make use of [variables](/documentation/server/gnatsd-config/#variables).
+Each permission grant is an object with two fields: what subject(s) the authenticated user can publish to, and what subject(s) the authenticated user can subscribe to. The parser is generous at understanding what the intent is, so both arrays and singletons are processed. Subjects themselves can contain wildcards. Permissions can make use of [variables](/doc/managing_the_server/configuration).
You set permissions by creating an entry inside of the `authorization` configuration block that conforms to the following syntax:
-```
+```ascii
authorization {
PERMISSION_NAME = {
publish = "singleton" or ["array", ...]
@@ -27,11 +24,13 @@ authorization {
}
```
-# Example
+**Important Note** NATS Authorizations are whitelist only, meaning in order to not break request/reply patterns you need to add rules as above with Alice and Bob for the `_INBOX.>` pattern. If an unauthorized client publishes or attempts to subscribe to a subject that has not been whitelisted, the action fails and is logged at the server, and an error message is returned to the client.
+
+### Example
Here is an example authorization configuration that defines four users, three of whom are assigned explicit permissions.
-```
+```ascii
authorization {
ADMIN = {
publish = ">"
@@ -49,7 +48,6 @@ authorization {
publish = "SANDBOX.*"
subscribe = ["PUBLIC.>", "_INBOX.>"]
}
-
PASS: abcdefghijklmnopqrstuvwxwz0123456789
users = [
{user: joe, password: foo, permissions: $ADMIN}
@@ -60,12 +58,10 @@ authorization {
}
```
-Since Joe is an ADMIN he can publish/subscribe on any subject. We use the wildcard “>” to match any subject.
+Since Joe is an ADMIN he can publish/subscribe on any subject. We use the wildcard `>` to match any subject.
-Alice is a REQUESTOR and can publish requests on subjects "req.foo" or "req.bar", and subscribe to anything that is a response ("_INBOX.>").
+Alice is a REQUESTOR and can publish requests on subjects `req.foo` or `req.bar`, and subscribe to anything that is a response (`_INBOX.>`).
Charlie has no permissions granted and therefore inherits the default permission set. You set the inherited default permissions by assigning them to the default_permissions entry inside of the authorization configuration block.
-Bob is a RESPONDER to any of Alice's requests, so Bob needs to be able to subscribe to the request subjects and respond to Alice's reply subject which will be an _INBOX.>.
-
-Important to note, NATS Authorizations are whitelist only, meaning in order to not break request/reply patterns you need to add rules as above with Alice and Bob for the _INBOX.> pattern. If an unauthorized client publishes or attempts to subscribe to a subject that has not been whitelisted, the action fails and is logged at the server, and an error message is returned to the client.
\ No newline at end of file
+Bob is a RESPONDER to any of Alice's requests, so Bob needs to be able to subscribe to the request subjects and respond to Alice's reply subject which will be an `_INBOX.>`.
diff --git a/content/documentation/server/gnatsd-cluster.md b/content/doc/managing_the_server/clustering.md
similarity index 66%
rename from content/documentation/server/gnatsd-cluster.md
rename to content/doc/managing_the_server/clustering.md
index 2a0fd66f..a05cbb23 100644
--- a/content/documentation/server/gnatsd-cluster.md
+++ b/content/doc/managing_the_server/clustering.md
@@ -1,37 +1,33 @@
+++
date = "2016-07-01"
-title = "Server Clustering"
+title = "Building NATS Server Clusters"
description = ""
category = "server"
[menu.main]
- name = "Server Clustering"
+ name = "Clustering"
weight = 7
- identifier = "server-gnatsd-cluster"
- parent = "Server"
+ identifier = "doc-clustering"
+ parent = "Managing the Server"
+++
-# NATS Server Clustering
-
NATS supports running each server in clustered mode. You can cluster servers together for high volume messaging systems and resiliency and high availability. Clients are cluster-aware.
-Note that NATS clustered servers have a forwarding limit of one hop. This means that each `gnatsd` instance will **only** forward messages that it has received **from a client** to the immediately adjacent `gnatsd` instances to which it has routes. Messages received **from** a route will only be distributed to local clients. Therefore a full mesh cluster, or complete graph, is recommended for NATS to function as intended and as described throughout the documentation.
+Note that NATS clustered servers have a forwarding limit of one hop. This means that each `gnatsd` instance will **only** forward messages that it has received **from a client** to the immediately adjacent `gnatsd` instances to which it has routes. Messages received **from** a route will only be distributed to local clients. Therefore a full mesh cluster, or complete graph, is recommended for NATS to function as intended and as described throughout the documentation.
-## Overview
+## Cluster URLs
In addition to a port for listening for clients, `gnatsd` can listen on a "cluster" URL (the `-cluster` option). Additional `gnatsd` servers can then add that URL to their `-routes` argument to join the cluster. These options can also be specified in a config file, but only the command-line version is shown in this overview for simplicity.
-Examples:
-
-No cluster:
+### Running with No Cluster
-```bash
+```sh
gnatsd -p 4222
```
----
-Simplest cluster:
+### Running a Simple Cluster
-```bash
+```sh
# Server A on 10.10.0.1
gnatsd -p 4222 -cluster nats://10.10.0.1:5222
@@ -41,38 +37,40 @@ gnatsd -p 4222 -cluster nats://10.10.0.2:5222 -routes nats://10.10.0.1:5222
----
-```bash
+```sh
# Server A on 10.10.0.1
gnatsd -p 4222 -cluster nats://10.10.0.1:5222 -routes nats://10.10.0.2:5222
# Server B on 10.10.0.2
-gnatsd -p 4222 -cluster nats://10.10.0.2:5222 -routes nats://10.10.0.1:5222
+gnatsd -p 4222 -cluster nats://10.10.0.2:5222 -routes nats://10.10.0.1:5222
```
Clients connecting to any server in the cluster will remain connected to the cluster even if the server it originally connected to is taken down, as long as at least a single server remains.
-## Usage
+## Command Line Options
The following cluster options are supported:
- --routes [rurl-1, rurl-2] Routes to solicit and connect
+ --routes [rurl-1, rurl-2] Routes to solicit and connect
--cluster nats://host:port Cluster URL for solicited routes
-When a NATS server routes to a specified URL, it will advertise its own cluster URL to all other servers in the route route effectively creating a routing mesh to all other servers. **Note:** when using the `-routes` option, you must also specify a `-cluster` option.
+When a NATS server routes to a specified URL, it will advertise its own cluster URL to all other servers in the route route effectively creating a routing mesh to all other servers.
+
+**Note:** when using the `-routes` option, you must also specify a `-cluster` option.
-Note that NATS server clustering can also be configured using the server config file.
+Clustering can also be configured using the server [config file](/doc/managing_the_server/configuration).
-## Example
+## Three Server Cluster Example
The following example demonstrates how to run a cluster of 3 servers on the same host. We will start with the seed server and use the `-D` command line parameter to produce debug information.
-```
+```sh
gnatsd -p 4222 -cluster nats://localhost:4248 -D
```
Alternatively, you could use a configuration file, let's call it `seed.conf`, with a content similar to this:
-```
+```ascii
# Cluster Seed Node
listen: 127.0.0.1:4222
@@ -85,13 +83,13 @@ cluster {
And start the server like this:
-```
+```sh
gnatsd -config ./seed.conf -D
```
This will produce an output similar to:
-```
+```sh
[75653] 2016/04/26 15:14:47.339321 [INF] Listening for route connections on 127.0.0.1:4248
[75653] 2016/04/26 15:14:47.340787 [INF] Listening for client connections on 127.0.0.1:4222
[75653] 2016/04/26 15:14:47.340822 [DBG] server id is xZfu3u7usAPWkuThomoGzM
@@ -100,7 +98,7 @@ This will produce an output similar to:
It is also possible to specify the hostname and port independently. At least the port is required. If you leave the hostname off it will bind to all the interfaces ('0.0.0.0').
-```
+```ascii
cluster {
host: 127.0.0.1
port: 4248
@@ -109,7 +107,7 @@ cluster {
Now let's start two more servers, each one connecting to the seed server.
-```
+```sh
gnatsd -p 5222 -cluster nats://localhost:5248 -routes nats://localhost:4248 -D
```
@@ -117,7 +115,7 @@ When running on the same host, we need to pick different ports for the client co
Here is the log produced. See how it connects and registers a route to the seed server (`...GzM`).
-```
+```sh
[75665] 2016/04/26 15:14:59.970014 [INF] Listening for route connections on localhost:5248
[75665] 2016/04/26 15:14:59.971150 [INF] Listening for client connections on 0.0.0.0:5222
[75665] 2016/04/26 15:14:59.971176 [DBG] server id is 53Yi78q96t52QdyyWLKIyE
@@ -131,7 +129,7 @@ Here is the log produced. See how it connects and registers a route to the seed
From the seed's server log, we see that the route is indeed accepted:
-```
+```sh
[75653] 2016/04/26 15:14:59.971602 [DBG] 127.0.0.1:52679 - rid:1 - Route connection created
[75653] 2016/04/26 15:14:59.971733 [DBG] 127.0.0.1:52679 - rid:1 - Registering remote route "53Yi78q96t52QdyyWLKIyE"
[75653] 2016/04/26 15:14:59.971739 [DBG] 127.0.0.1:52679 - rid:1 - Route sent local subscriptions
@@ -139,13 +137,13 @@ From the seed's server log, we see that the route is indeed accepted:
Finally, let's start the third server:
-```
+```sh
gnatsd -p 6222 -cluster nats://localhost:6248 -routes nats://localhost:4248 -D
```
Again, notice that we use a different client port and cluster address, but still point to the same seed server at the address `nats://localhost:4248`:
-```
+```sh
[75764] 2016/04/26 15:19:11.528185 [INF] Listening for route connections on localhost:6248
[75764] 2016/04/26 15:19:11.529787 [INF] Listening for client connections on 0.0.0.0:6222
[75764] 2016/04/26 15:19:11.529829 [DBG] server id is IRepas80TBwJByULX1ulAp
@@ -164,7 +162,7 @@ First a route is created to the seed server (`...GzM`) and after that, a route f
The log from the seed server shows that it accepted the route from the third server:
-```
+```sh
[75653] 2016/04/26 15:19:11.530308 [DBG] 127.0.0.1:52726 - rid:2 - Route connection created
[75653] 2016/04/26 15:19:11.530384 [DBG] 127.0.0.1:52726 - rid:2 - Registering remote route "IRepas80TBwJByULX1ulAp"
[75653] 2016/04/26 15:19:11.530389 [DBG] 127.0.0.1:52726 - rid:2 - Route sent local subscriptions
@@ -172,7 +170,7 @@ The log from the seed server shows that it accepted the route from the third ser
And the log from the second server shows that it connected to the third.
-```
+```sh
[75665] 2016/04/26 15:19:11.530469 [DBG] Trying to connect to route on 127.0.0.1:6248
[75665] 2016/04/26 15:19:11.530565 [DBG] 127.0.0.1:6248 - rid:2 - Route connection created
[75665] 2016/04/26 15:19:11.530570 [DBG] 127.0.0.1:6248 - rid:2 - Route connect msg sent
@@ -182,170 +180,11 @@ And the log from the second server shows that it connected to the third.
At this point, there is a full mesh cluster of NATS servers.
-## Clustering examples using the NATS Server Docker image
-
-Below is an example of how to setup gnatsd cluster using Docker.
-
-We put 3 different configurations (one per gnatsd server) under a folder named conf as follows:
-
-```
-|-- conf
- |-- gnatsd-A.conf
- |-- gnatsd-B.conf
- |-- gnatsd-C.conf
-```
-
-Each one of those files have the following content below: (Here I am using ip 192.168.59.103 as an example, so just replace with the proper ip from your server)
-
-
-### Example 1: Setting up a cluster on 3 different servers provisioned beforehand
-
-**gnatsd-A**
-
-```
-# Cluster Server A
-
-port: 7222
-
-cluster {
- host: '0.0.0.0'
- port: 7244
-
- routes = [
- nats-route://192.168.59.103:7246
- nats-route://192.168.59.103:7248
- ]
-}
-```
-
-**gnatsd-B**
-
-```
-# Cluster Server B
-
-port: 8222
-
-cluster {
- host: '0.0.0.0'
- port: 7246
-
- routes = [
- nats-route://192.168.59.103:7244
- nats-route://192.168.59.103:7248
- ]
-}
-```
-
-**gnatsd-C**
-
-```
-# Cluster Server C
-
-port: 9222
-
-cluster {
- host: '0.0.0.0'
- port: 7248
-
- routes = [
- nats-route://192.168.59.103:7244
- nats-route://192.168.59.103:7246
- ]
-}
-```
-
-Starting the containers
-
-Then on each one of your servers, you should be able to start the gnatsd image as follows:
-
-```
-docker run -it -p 0.0.0.0:7222:7222 -p 0.0.0.0:7244:7244 --rm -v $(pwd)/conf/gnatsd-A.conf:/tmp/cluster.conf nats -c /tmp/cluster.conf -p 7222 -D -V
-```
-
-```
-docker run -it -p 0.0.0.0:8222:8222 -p 0.0.0.0:7246:7246 --rm -v $(pwd)/conf/gnatsd-B.conf:/tmp/cluster.conf nats -c /tmp/cluster.conf -p 8222 -D -V
-```
-
-```
-docker run -it -p 0.0.0.0:9222:9222 -p 0.0.0.0:7248:7248 --rm -v $(pwd)/conf/gnatsd-C.conf:/tmp/cluster.conf nats -c /tmp/cluster.conf -p 9222 -D -V
-```
-
-### Example 2: Setting a gnatsd cluster one by one
-
-In this scenario:
-
-- We bring up A and get its ip (nats-route://192.168.59.103:7244)
-- Then create B and then use address of A in its configuration.
-- Get the address of B nats-route://192.168.59.104:7246 and create C and use the addresses of A and B.
-
-First, we create the Node A and start up a gnatsd server with the following config:
-
-```
-# Cluster Server A
-
-port: 4222
-
-cluster {
- host: '0.0.0.0'
- port: 7244
-
-}
-```
-
-```
-docker run -it -p 0.0.0.0:4222:4222 -p 0.0.0.0:7244:7244 --rm -v $(pwd)/conf/gnatsd-A.conf:/tmp/cluster.conf nats -c /tmp/cluster.conf -p 4222 -D -V
-```
-
-Then we proceed to create the next node. We realize that the first node has ip:port as `192.168.59.103:7244` so we add this to the routes configuration as follows:
-
-```
-# Cluster Server B
-
-port: 4222
-
-cluster {
- host: '0.0.0.0'
- port: 7244
-
- routes = [
- nats-route://192.168.59.103:7244
- ]
-}
-```
-
-Then start server B:
-
-```
-docker run -it -p 0.0.0.0:4222:4222 -p 0.0.0.0:7244:7244 --rm -v $(pwd)/conf/gnatsd-B.conf:/tmp/cluster.conf nats -c /tmp/cluster.conf -p 4222 -D -V
-```
-
-Finally, we create another Node C. We now know the routes of A and B so we can add it to its configuration:
-
-```
-# Cluster Server C
-
-port: 4222
-
-cluster {
- host: '0.0.0.0'
- port: 7244
-
- routes = [
- nats-route://192.168.59.103:7244
- nats-route://192.168.59.104:7244
- ]
-}
-```
-
-Then start it:
-
-```
-docker run -it -p 0.0.0.0:4222:4222 -p 0.0.0.0:7244:7244 --rm -v $(pwd)/conf/gnatsd-C.conf:/tmp/cluster.conf nats -c /tmp/cluster.conf -p 9222 -D -V
-```
+### Testing the Cluster
Now, the following should work: make a subscription to Node A then publish to Node C. You should be able to to receive the message without problems.
-```
+```sh
nats-sub -s "nats://192.168.59.103:7222" hello &
nats-pub -s "nats://192.168.59.105:7222" hello world
diff --git a/content/documentation/server/gnatsd-config.md b/content/doc/managing_the_server/configuration.md
similarity index 80%
rename from content/documentation/server/gnatsd-config.md
rename to content/doc/managing_the_server/configuration.md
index 41ed74c8..5a6e5319 100644
--- a/content/documentation/server/gnatsd-config.md
+++ b/content/doc/managing_the_server/configuration.md
@@ -1,18 +1,15 @@
+++
-date = "2015-09-27"
-title = "Server Configuration"
+title = "NATS Server Configuration"
description = ""
category = "server"
[menu.main]
- name = "Server Configuration"
- weight = 5
- identifier = "server-gnatsd-config"
- parent = "Server"
+ name = "Configuration"
+ weight = 6
+ identifier = "doc-configuration"
+ parent = "Managing the Server"
+++
-# NATS Server Configuration
-
-You use a server configuration file to configure the NATS server, including:
+You can use a server configuration file to configure the NATS server, including:
- Client listening port
- HTTP monitoring port
@@ -34,24 +31,24 @@ The config file format supports the following syntax:
- Mixed Arrays: `[...]`
- Nested Maps: `{...}`
- Multiple comment types: `#` and `//`
-- Key value assigments using:
- - Equals sign (`foo = 2`)
- - Colon (`foo: 2`)
- - Whitespace (`foo 2`)
+- Key value assignments using:
+ - Equals sign (`foo = 2`)
+ - Colon (`foo: 2`)
+ - Whitespace (`foo 2`)
- Maps can be assigned with no key separator
- Semicolons as value terminators in key/value assignments are optional
-In general the configuration parameters are the same as the [command line arguments](http://nats.io/documentation/server/gnatsd-usage/). Note, however, the following differences:
+In general the configuration parameters are the same as the [command line arguments](/doc/managing_the_server/running). Note, however, the following differences:
-- The listen option is host:port for connections, on the server cli its -a and -p no hostport is supported.
-- http/https is only port on the cli, on the config it is host:port (there’s no config flag for the interface for the monitoring)
+- The listen option is host:port for connections, on the server command line it is -a and -p, no hostport is supported.
+- http/https is only a port on the command line, on the config it is host:port (there’s no config flag for the interface for the monitoring)
- The -cluster flag is used for defining the host:port where routes can be solicited, on the config file this is called ‘listen’ as part property of a ‘cluster’ object.
## Sample server config file
The following demonstrates an example NATS server config file. See also the [NATS Server README](https://github.com/nats-io/gnatsd/blob/master/README.md#configuration-file)
-```
+```ascii
port: 4242 # port to listen for client connections
net: localhost # optional listen interface, default is 0.0.0.0 (all)
@@ -114,13 +111,13 @@ max_payload: 65536
## Variables
-The NATS server configuration file format supports the use of block-scoped variables which can be used for templating in the configuration file, and specifically to ease setting of group values for permission fields.
+The NATS server configuration file format supports the use of block-scoped variables which can be used for templating in the configuration file, and specifically to ease setting of group values for permission fields.
-Variables can be referenced by the prefix `$`, e.g. `$PASSWORD`. Variables can be defined in the configuration file itself or reference environment variables.
+Variables can be referenced by the prefix `$`, e.g. `$PASSWORD`. Variables can be defined in the configuration file itself or *reference environment variables*.
For example:
-```
+```ascii
authorization {
PASS: abcdefghijklmnopqrstuvwxyz0123456789
users = [
diff --git a/content/doc/managing_the_server/containerization.md b/content/doc/managing_the_server/containerization.md
new file mode 100644
index 00000000..e95b5238
--- /dev/null
+++ b/content/doc/managing_the_server/containerization.md
@@ -0,0 +1,267 @@
++++
+date = "2015-09-27"
+title = "Containerizing the NATS Server"
+description = ""
+category = "server"
+[menu.main]
+ name = "Containerization"
+ weight = 8
+ identifier = "doc-containerization"
+ parent = "Managing the Server"
++++
+
+The NATS server is provided as a Docker image on [Docker Hub](https://hub.docker.com/_/nats/) that you can run using the Docker daemon. The NATS server Docker image is extremely lightweight, coming in under 10 MB in size.
+
+Synadia actively maintains and supports the NATS server Docker image.
+
+### Usage
+
+To use the Docker container image, install Docker and pull the public image:
+
+```sh
+> docker pull nats
+```
+
+Run the NATS server image:
+
+```sh
+> docker run -d --name nats-main nats
+```
+
+By default the NATS server exposes multiple ports:
+
+- 4222 is for clients.
+- 8222 is an HTTP management port for information reporting.
+- 6222 is a routing port for clustering.
+- Use -p or -P to customize.
+
+For example:
+
+```sh
+$ docker run -d --name nats-main nats
+[INF] Starting gnatsd version 0.6.6
+[INF] Starting http monitor on port 8222
+[INF] Listening for route connections on 0.0.0.0:6222
+[INF] Listening for client connections on 0.0.0.0:4222
+[INF] gnatsd is ready
+```
+
+To run with the ports exposed on the host:
+
+```sh
+> docker run -d -p 4222:4222 -p 6222:6222 -p 8222:8222 --name nats-main nats
+```
+
+To run a second server and cluster them together:
+
+```sh
+> docker run -d --name=nats-2 --link nats-main nats --routes=nats-route://ruser:T0pS3cr3t@nats-main:6222
+```
+
+**NOTE** Since the Docker image protects routes using credentials we need to provide them above. Extracted [from Docker image configuration](https://github.com/nats-io/nats-docker/blob/master/amd64/gnatsd.conf#L16-L20)
+
+```ascii
+# Routes are protected, so need to use them with --routes flag
+# e.g. --routes=nats-route://ruser:T0pS3cr3t@otherdockerhost:6222
+authorization {
+ user: ruser
+ password: T0pS3cr3t
+ timeout: 2
+}
+```
+
+To verify the routes are connected:
+
+```sh
+$ docker run -d --name=nats-2 --link nats-main nats --routes=nats-route://ruser:T0pS3cr3t@nats-main:6222 -DV
+[INF] Starting gnatsd version 0.6.6
+[INF] Starting http monitor on port 8222
+[INF] Listening for route connections on :6222
+[INF] Listening for client connections on 0.0.0.0:4222
+[INF] gnatsd is ready
+[DBG] Trying to connect to route on nats-main:6222
+[DBG] 172.17.0.52:6222 - rid:1 - Route connection created
+[DBG] 172.17.0.52:6222 - rid:1 - Route connect msg sent
+[DBG] 172.17.0.52:6222 - rid:1 - Registering remote route "ee35d227433a738c729f9422a59667bb"
+[DBG] 172.17.0.52:6222 - rid:1 - Route sent local subscriptions
+```
+
+## Clustering With Docker
+
+Below is are a couple examples of how to setup gnatsd cluster using Docker. We put 3 different configurations (one per gnatsd server) under a folder named conf as follows:
+
+```ascii
+|-- conf
+ |-- gnatsd-A.conf
+ |-- gnatsd-B.conf
+ |-- gnatsd-C.conf
+```
+
+Each one of those files have the following content below: (Here I am using ip 192.168.59.103 as an example, so just replace with the proper ip from your server)
+
+### Example 1: Setting up a cluster on 3 different servers provisioned beforehand
+
+In this example, the three servers are started with config files that know about the other servers.
+
+#### gnatsd-A
+
+```ascii
+# Cluster Server A
+
+port: 7222
+
+cluster {
+ host: '0.0.0.0'
+ port: 7244
+
+ routes = [
+ nats-route://192.168.59.103:7246
+ nats-route://192.168.59.103:7248
+ ]
+}
+```
+
+#### gnatsd-B
+
+```ascii
+# Cluster Server B
+
+port: 8222
+
+cluster {
+ host: '0.0.0.0'
+ port: 7246
+
+ routes = [
+ nats-route://192.168.59.103:7244
+ nats-route://192.168.59.103:7248
+ ]
+}
+```
+
+#### gnatsd-C
+
+```ascii
+# Cluster Server C
+
+port: 9222
+
+cluster {
+ host: '0.0.0.0'
+ port: 7248
+
+ routes = [
+ nats-route://192.168.59.103:7244
+ nats-route://192.168.59.103:7246
+ ]
+}
+```
+
+To start the containers, on each one of your servers, you should be able to start the gnatsd image as follows:
+
+```sh
+docker run -it -p 0.0.0.0:7222:7222 -p 0.0.0.0:7244:7244 --rm -v $(pwd)/conf/gnatsd-A.conf:/tmp/cluster.conf nats -c /tmp/cluster.conf -p 7222 -D -V
+```
+
+```
+docker run -it -p 0.0.0.0:8222:8222 -p 0.0.0.0:7246:7246 --rm -v $(pwd)/conf/gnatsd-B.conf:/tmp/cluster.conf nats -c /tmp/cluster.conf -p 8222 -D -V
+```
+
+```
+docker run -it -p 0.0.0.0:9222:9222 -p 0.0.0.0:7248:7248 --rm -v $(pwd)/conf/gnatsd-C.conf:/tmp/cluster.conf nats -c /tmp/cluster.conf -p 9222 -D -V
+```
+
+### Example 2: Setting a gnatsd cluster one by one
+
+In this scenario:
+
+- We bring up A and get its ip (nats-route://192.168.59.103:7244)
+- Then create B and then use address of A in its configuration.
+- Get the address of B nats-route://192.168.59.104:7246 and create C and use the addresses of A and B.
+
+First, we create the Node A and start up a gnatsd server with the following config:
+
+```ascii
+# Cluster Server A
+
+port: 4222
+
+cluster {
+ host: '0.0.0.0'
+ port: 7244
+
+}
+```
+
+```sh
+docker run -it -p 0.0.0.0:4222:4222 -p 0.0.0.0:7244:7244 --rm -v $(pwd)/conf/gnatsd-A.conf:/tmp/cluster.conf nats -c /tmp/cluster.conf -p 4222 -D -V
+```
+
+Then we proceed to create the next node. We realize that the first node has ip:port as `192.168.59.103:7244` so we add this to the routes configuration as follows:
+
+```ascii
+# Cluster Server B
+
+port: 4222
+
+cluster {
+ host: '0.0.0.0'
+ port: 7244
+
+ routes = [
+ nats-route://192.168.59.103:7244
+ ]
+}
+```
+
+Then start server B:
+
+```sh
+docker run -it -p 0.0.0.0:4222:4222 -p 0.0.0.0:7244:7244 --rm -v $(pwd)/conf/gnatsd-B.conf:/tmp/cluster.conf nats -c /tmp/cluster.conf -p 4222 -D -V
+```
+
+Finally, we create another Node C. We now know the routes of A and B so we can add it to its configuration:
+
+```ascii
+# Cluster Server C
+
+port: 4222
+
+cluster {
+ host: '0.0.0.0'
+ port: 7244
+
+ routes = [
+ nats-route://192.168.59.103:7244
+ nats-route://192.168.59.104:7244
+ ]
+}
+```
+
+Then start it:
+
+```sh
+docker run -it -p 0.0.0.0:4222:4222 -p 0.0.0.0:7244:7244 --rm -v $(pwd)/conf/gnatsd-C.conf:/tmp/cluster.conf nats -c /tmp/cluster.conf -p 9222 -D -V
+```
+
+### Testing the Clusters
+
+Now, the following should work: make a subscription to Node A then publish to Node C. You should be able to to receive the message without problems.
+
+```sh
+nats-sub -s "nats://192.168.59.103:7222" hello &
+
+nats-pub -s "nats://192.168.59.105:7222" hello world
+
+[#1] Received on [hello] : 'world'
+
+# GNATSD on Node C logs:
+[1] 2015/06/23 05:20:31.100032 [TRC] 192.168.59.103:7244 - rid:2 - <<- [MSG hello RSID:8:2 5]
+
+# GNATSD on Node A logs:
+[1] 2015/06/23 05:20:31.100600 [TRC] 10.0.2.2:51007 - cid:8 - <<- [MSG hello 2 5]
+```
+
+## Tutorial
+
+See the [NATS Docker tutorial](/doc/additional_documentation/gnatsd-docker/) for more instructions on using the NATS server Docker image.
diff --git a/content/doc/managing_the_server/installing.md b/content/doc/managing_the_server/installing.md
new file mode 100644
index 00000000..084a3cbe
--- /dev/null
+++ b/content/doc/managing_the_server/installing.md
@@ -0,0 +1,68 @@
++++
+title = "Installing the NATS Server"
+description = ""
+category = "server"
+[menu.main]
+ name = "Installation"
+ weight = 1
+ identifier = "doc-installing-gnatsd"
+ parent = "Managing the Server"
++++
+
+There are numerous ways to install the NATS server.
+
+### Install From Binary
+
+The latest official release binaries are always available on the [GitHub releases page](https://github.com/nats-io/gnatsd/releases). The following platforms are available:
+
+* Linux (x86, x86_64, ARM)
+* Windows (x86, x86_64)
+* macOS
+
+### Alternative/Platform Specific Methods
+
+> **The following methods may not all install the latest released version**
+
+#### Go
+
+Make sure [your Go environment is set up](/doc/additional_documentation/go-install/), then install using `go get`.
+
+```sh
+go get github.com/nats-io/gnatsd
+```
+
+#### Docker Hub
+
+The latest [official Docker image](https://hub.docker.com/_/nats/) is available on Docker Hub.
+
+#### Windows
+
+On Windows, the NATS server can be installed via [Chocolatey](https://chocolatey.org/packages/gnatsd):
+
+```sh
+choco install gnatsd
+```
+
+#### macOS
+
+On macOS, the NATS server can be installed via [Homebrew](http://brewformulas.org/Gnatsd):
+
+```sh
+brew install gnatsd
+```
+
+### Test Your Installation
+
+To test your installation, you can invoke the NATS server binary, with no options and no configuration file (no authentication, no clustering).
+
+```sh
+gnatsd
+```
+
+When the server starts successfully, you will see that the NATS server listens for client connections on TCP Port 4222:
+
+```sh
+[18141] 2016/10/31 13:13:40.732616 [INF] Starting nats-server version 0.9.4
+[18141] 2016/10/31 13:13:40.732704 [INF] Listening for client connections on 0.0.0.0:4222
+[18141] 2016/10/31 13:13:40.732967 [INF] Server is ready
+```
diff --git a/content/documentation/server/gnatsd-logging.md b/content/doc/managing_the_server/logging.md
similarity index 68%
rename from content/documentation/server/gnatsd-logging.md
rename to content/doc/managing_the_server/logging.md
index 84ebc7b3..b98be3e4 100644
--- a/content/documentation/server/gnatsd-logging.md
+++ b/content/doc/managing_the_server/logging.md
@@ -1,20 +1,20 @@
+++
date = "2015-09-27"
-title = "Server Logging"
+title = "NATS Server Logging"
description = ""
category = "server"
[menu.main]
- name = "Server Logging"
- weight = 4
- identifier = "server-gnatsd-logging"
- parent = "Server"
+ name = "Logging"
+ weight = 9
+ identifier = "doc-logging"
+ parent = "Managing the Server"
+++
-# NATS Server Logging
+The NATS server provides various logging options that you can set via the command line or the configuration file.
-The NATS server provides various logging options.
+## Configuring Logging
-## Logging options
+### Command Line Options
The following logging operations are supported:
@@ -26,57 +26,62 @@ The following logging operations are supported:
-V, --trace Trace the raw protocol.
-DV Debug and Trace.
-## Debug and trace
+#### Debug and trace
The `-DV` flag enables trace and debug for the server.
-```
+```sh
gnatsd -DV -m 8222 -user foo -pass bar
```
-## Log file redirect
+#### Log file redirect
-```
+```sh
gnatsd -DV -m 8222 -l nats.log
```
-## Timestamp
+#### Timestamp
If `-T false` then log entries are not timestamped. Default is true.
-## Syslog
+#### Syslog
-```
+You can configure syslog with `UDP`:
+
+```sh
gnatsd -s udp://localhost:514
```
-```
+or `syslog:`
+
+```sh
gnatsd -r syslog://:
```
For example:
-```
+```sh
syslog://logs.papertrailapp.com:26900
```
-## Config file example
+### Using the Configuration File
-```
-# logging options
+All of these settings are available in the configuration file as well.
+
+```ascii
debug: false
trace: true
logtime: false
log_file: "/tmp/gnatsd.log"
```
-## Log rotation with logrotate
+## Log Rotation with logrotate
NATS server does not provide tools to manage log files, but it does include mechanisms that make log rotation simple. We can use this mechanism with [logrotate](https://github.com/logrotate/logrotate); a simple standard Linux utility to rotate logs available on most distributions like Debian, Ubuntu, RedHat (CentOS), etc.
-Simple custom logrotate script is below:
+For example, you could configure `logrotate` with:
-```
+```ascii
/path/to/gnatsd.log {
daily
rotate 30
@@ -84,7 +89,7 @@ Simple custom logrotate script is below:
missingok
notifempty
postrotate
- kill -SIGUSR1 `cat /var/run/gnatsd.pid`
+ kill -SIGUSR1 `cat /var/run/gnatsd.pid`
endscript
}
```
@@ -96,3 +101,7 @@ The rest of the file specifies that the logs will rotate daily ("daily" option)
The "postrotate" section tells NATS server to reload the log files once the rotation is complete. The command ```kill -SIGUSR1 `cat /var/run/gnatsd.pid` ``` does not kill the NATS server process, but instead sends it a signal causing it to reload its log files. This will cause new requests to be logged to the refreshed log file.
The `/var/run/gnatsd.pid` file is where NATS server stores the master process's pid.
+
+## Some Logging Notes
+
+- The NATS Server, in verbose mode, will log the receipt of `UNSUB` messages, but this does not indicate the subscription is gone, only that the message was received. The `DELSUB` message in the log can be used to determine when the actual subscription removal has taken place.
\ No newline at end of file
diff --git a/content/documentation/server/gnatsd-monitoring.md b/content/doc/managing_the_server/monitoring.md
similarity index 82%
rename from content/documentation/server/gnatsd-monitoring.md
rename to content/doc/managing_the_server/monitoring.md
index 4f197f85..2a10bda8 100644
--- a/content/documentation/server/gnatsd-monitoring.md
+++ b/content/doc/managing_the_server/monitoring.md
@@ -1,46 +1,36 @@
+++
-date = "2015-09-27"
-title = "Server Monitoring"
+title = "Monitoring the NATS Server"
description = ""
category = "server"
[menu.main]
- name = "Server Monitoring"
- weight = 9
- identifier = "server-gnatsd-monitoring"
- parent = "Server"
+ name = "Monitoring"
+ weight = 10
+ identifier = "doc-monitoring"
+ parent = "Managing the Server"
+++
-# NATS Server Monitoring
-
-To monitor the NATS messaging system, NATS provides a lightweight HTTP server on a dedicated monitoring port. The monitoring server provides several endpoints, including [varz](#/varz), [connz](#/connz), [routez](#/routez), and [subsz](#/subz). All endpoints return a JSON object.
+To monitor the NATS messaging system, `gnatsd` provides a lightweight HTTP server on a dedicated monitoring port. The monitoring server provides several endpoints, including [varz](#/varz), [connz](#/connz), [routez](#/routez), and [subsz](#/subz). All endpoints return a JSON object.
The NATS monitoring endpoints support JSONP and CORS, making it easy to create single page monitoring web applications.
## Enabling monitoring
-To enable the monitoring server, start the NATS server with the monitoring flag `-m` and the monitoring port.
-
-Monitoring options
+To enable the monitoring server, start the NATS server with the monitoring flag `-m` and the monitoring port, or turn it on in the [configuration file](/doc/managing_the_server/configuration).
-m, --http_port PORT HTTP PORT for monitoring
-ms,--https_port PORT Use HTTPS PORT for monitoring
Example:
-```
-gnatsd -m 8222
-```
-
-You should see that the NATS server starts with the HTTP monitoring port enabled:
-
-```
+```sh
+$ gnatsd -m 8222
[4528] 2015/08/19 20:09:58.572939 [INF] Starting gnatsd version 0.8.0
[4528] 2015/08/19 20:09:58.573007 [INF] Starting http monitor on port 8222
[4528] 2015/08/19 20:09:58.573071 [INF] Listening for client connections on 0.0.0.0:4222
[4528] 2015/08/19 20:09:58.573090 [INF] gnatsd is ready
```
-To test, run '``gnatsd -m 8222``', then go to http://localhost:8222/
+To test, run `gnatsd -m 8222`, then go to http://localhost:8222/
## Monitoring endpoints
@@ -50,7 +40,7 @@ The following sections describe each supported monitoring endpoint: `varz`, `con
The endpoint http://localhost:8222/varz reports various general statistics.
-```
+```json
{
"server_id": "ec933edcd2bd86bcf71d555fc8b4fb2c",
"version": "0.6.6",
@@ -91,7 +81,7 @@ You can control these via URL arguments (limit and offset). For example: http://localhost:8222/connz?limit=1&offset=1&subs=1.
-```
+```json
{
"now": "2015-07-14T13:30:59.349179963-07:00",
"num_connections": 2,
@@ -140,7 +130,7 @@ The endpoint http://local
The `routez` endpoint does support the `subs` argument from the `/connz` endpoint. For example: http://localhost:8222/routez?subs=1
-```
+```json
{
"now": "2015-07-14T13:30:59.349179963-07:00",
"num_routes": 1,
@@ -164,9 +154,9 @@ The `routez` endpoint does support the `subs` argument from the `/connz` endpoin
### /subsz
-The endpoint http://localhost:8222/subscriptionsz reports detailed information about the current subscriptions and the routing data structure.
+The endpoint http://localhost:8222/subz reports detailed information about the current subscriptions and the routing data structure.
-```
+```json
{
"num_subscriptions": 3,
"num_cache": 0,
@@ -186,13 +176,13 @@ NATS monitoring endpoints support [JSONP](https://en.wikipedia.org/wiki/JSONP) a
For example:
-```
+```sh
http://localhost:8222/connz?callback=cb
```
Here is a JQuery example implementation:
-```
+```javascript
$.getJSON('http://localhost:8222/connz?callback=?', function(data) {
console.log(data);
});
diff --git a/content/doc/managing_the_server/running.md b/content/doc/managing_the_server/running.md
new file mode 100644
index 00000000..1c46c9b8
--- /dev/null
+++ b/content/doc/managing_the_server/running.md
@@ -0,0 +1,100 @@
++++
+title = "Running the NATS Server"
+description = ""
+category = "server"
+[menu.main]
+ name = "Running the Server"
+ weight = 2
+ identifier = "doc-running-gnatsd"
+ parent = "Managing the Server"
++++
+
+Out-of-the-box you can run the NATS server without any custom settings.
+
+```sh
+gnatsd
+```
+
+### Starting the NATS server with monitoring enabled (optional)
+
+The NATS server exposes a monitoring interface on port 8222.
+
+```
+gnatsd -m 8222
+```
+
+If you run the NATS server with monitoring enabled, you see the following messages:
+
+```
+[18159] 2016/10/31 13:14:03.055572 [INF] Starting nats-server version 0.9.4
+[18159] 2016/10/31 13:14:03.055692 [INF] Starting http monitor on 0.0.0.0:8222
+[18159] 2016/10/31 13:14:03.055762 [INF] Listening for client connections on 0.0.0.0:4222
+[18159] 2016/10/31 13:14:03.055796 [INF] Server is ready
+```
+
+## Command Line Options
+
+There are two ways to configure the server. You can include one or more command line arguments as described below, or you can use a [configuration file](/doc/managing_the_server/configuration).
+
+### Common Options
+
+ -h, --help Show this message
+ -v, --version Show version
+
+### Server Options
+
+ -a, --addr HOST Bind to HOST address (default is `0.0.0.0`).
+ -p, --port PORT PORT for client connections (default is `4222`).
+ -P, --pid FILE File path to store PID.
+ -m, --http_port PORT HTTP PORT for monitoring (use `-m 8222` to enable).
+ -ms,--https_port PORT Use HTTPS PORT for monitoring
+ -c, --config FILE File path to server configuration.
+ -client_advertise HOST:PORT Configure the HOST and PORT returned in the INFO message
+
+See [Configuration](/doc/managing_the_server/configuration).
+
+### Logging options
+
+ -l, --log FILE File to redirect log output
+ -T, --logtime Timestamp log entries (default: true)
+ -s, --syslog Enable syslog as log method.
+ -r, --remote_syslog Syslog server addr (udp://localhost:514).
+ -D, --debug Enable debugging output
+ -V, --trace Trace the raw protocol
+ -DV Debug and Trace
+
+See [Logging](/doc/managing_the_server/logging).
+
+### Single User Authentication options
+
+ --user user User required for connections
+ --pass password Password required for connections
+ --auth token Token required for connections
+
+See [Authentication](/doc/managing_the_server/authentication).
+
+### TLS Options
+
+ --help_tls TLS help
+ --tls Enable TLS, do not verify clients (default: false)
+ --tlscert FILE Server certificate file
+ --tlskey FILE Private key for server certificate
+ --tlsverify Enable TLS, verify client certificates
+ --tlscacert FILE Client certificate CA for verification
+
+### Cluster Options
+
+ --routes [rurl-1, rurl-2] Routes to solicit and connect
+ --cluster [cluster url] Cluster URL for solicited routes
+
+See [Clustering](/doc/managing_the_server/clustering).
+
+If routing is enabled, route (server) connections listen on port 6222.
+
+```
+[18159] 2016/10/31 13:14:03.055572 [INF] Starting nats-server version 0.9.4
+[18159] 2016/10/31 13:14:03.055692 [INF] Starting http monitor on 0.0.0.0:8222
+[18159] 2016/10/31 13:14:03.055707 [INF] Listening for route connections on 0.0.0.0:6222
+[18159] 2016/10/31 13:14:03.055762 [INF] Listening for client connections on 0.0.0.0:4222
+[18159] 2016/10/31 13:14:03.055796 [INF] Server is ready
+```
diff --git a/content/documentation/server/gnatsd-tls.md b/content/doc/managing_the_server/security.md
similarity index 90%
rename from content/documentation/server/gnatsd-tls.md
rename to content/doc/managing_the_server/security.md
index cbb5104e..a95c8824 100644
--- a/content/documentation/server/gnatsd-tls.md
+++ b/content/doc/managing_the_server/security.md
@@ -1,30 +1,27 @@
+++
-date = "2015-09-27"
-title = "NATS Server TLS and bcrypt"
+title = "NATS Server Security"
description = ""
category = "server"
-[menu.documentation]
- name = "NATS Server TLS and bcrypt"
- weight = 1
- identifier = "server-gnatsd-tls"
- parent = "server"
+[menu.main]
+ name = "Security/Encryption"
+ weight = 4
+ identifier = "doc-security"
+ parent = "Managing the Server"
+++
-### Using TLS
-
As of Release 0.7.0, the server can use modern TLS semantics for client connections, route connections, and the HTTPS monitoring port.
-The server requires TLS version 1.2, and sets preferences for modern cipher suites that avoid those known with vunerabilities. The
+The server requires TLS version 1.2, and sets preferences for modern cipher suites that avoid those known with vulnerabilities. The
server's preferences when building with Go1.5 are as follows.
```go
func defaultCipherSuites() []uint16 {
- return []uint16{
- // The SHA384 versions are only in Go1.5+
- tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
- tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
- tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
- tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
- }
+ return []uint16{
+ // The SHA384 versions are only in Go1.5+
+ tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+ tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+ tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+ tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ }
}
```
@@ -33,7 +30,7 @@ Generating self signed certs and intermediary certificate authorities is beyond
The server **requires** a certificate and private key. Optionally the server can require that clients need to present certificates, and the server can be configured with a CA authority to verify the client certificates.
-```
+```ascii
# Simple TLS config file
listen: 127.0.0.1:4443
@@ -53,7 +50,7 @@ authorization {
If requiring client certificates as well, simply change the TLS section as follows.
-```
+```ascii
tls {
cert_file: "./configs/certs/server-cert.pem"
key_file: "./configs/certs/server-key.pem"
@@ -64,7 +61,7 @@ tls {
When setting up clusters, all servers in the cluster, if using TLS, will both verify the connecting endpoints and the server responses. So certificates are checked in both directions. Certificates can be configured only for the server's cluster identity, keeping client and server certificates separate from cluster formation.
-```
+```ascii
cluster {
listen: 127.0.0.1:4244
@@ -98,7 +95,7 @@ The server can be run using command line arguments to enable TLS functionality.
Examples using the test certicates which are self signed for localhost and 127.0.0.1.
-```bash
+```sh
> ./gnatsd --tls --tlscert=./test/configs/certs/server-cert.pem --tlskey=./test/configs/certs/server-key.pem
[2935] 2016/04/26 13:34:30.685413 [INF] Starting nats-server version 0.8.0.beta
@@ -109,7 +106,7 @@ Examples using the test certicates which are self signed for localhost and 127.0
Notice that the log indicates that the client connections will be required to use TLS. If you run the server in Debug mode with -D or -DV, the logs will show the cipher suite selection for each connected client.
-```
+```sh
[15146] 2015/12/03 12:38:37.733139 [DBG] ::1:63330 - cid:1 - Starting TLS client connection handshake
[15146] 2015/12/03 12:38:37.751948 [DBG] ::1:63330 - cid:1 - TLS handshake complete
[15146] 2015/12/03 12:38:37.751959 [DBG] ::1:63330 - cid:1 - TLS version 1.2, cipher suite TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
@@ -117,11 +114,11 @@ Notice that the log indicates that the client connections will be required to u
If you want the server to enforce and require client certificates as well via the command line, utilize this example.
-```
+```sh
> ./gnatsd --tlsverify --tlscert=./test/configs/certs/server-cert.pem --tlskey=./test/configs/certs/server-key.pem --tlscacert=./test/configs/certs/ca.pem
```
-### Using bcrypt
+### Using bcrypt to Protect Passwords
In addition to TLS functionality, the server now also supports hashing of passwords and authentication tokens using `bcrypt`. To take advantage of this, simply replace the plaintext password in the configuration with its `bcrypt` hash, and the server will automatically utilize `bcrypt` as needed.
diff --git a/content/documentation/server/gnatsd-slow-consumers.md b/content/doc/managing_the_server/slow_consumers.md
similarity index 80%
rename from content/documentation/server/gnatsd-slow-consumers.md
rename to content/doc/managing_the_server/slow_consumers.md
index 05a8f6a8..10812efb 100644
--- a/content/documentation/server/gnatsd-slow-consumers.md
+++ b/content/doc/managing_the_server/slow_consumers.md
@@ -5,18 +5,20 @@ description = ""
category = "server"
[menu.main]
name = "Slow Consumers"
- weight = 11
- identifier = "server-slow-consumers"
- parent = "Server"
+ weight = 12
+ identifier = "doc-slow-consumers"
+ parent = "Managing the Server"
+++
+To support resiliency and high availability, NATS provides built-in mechanisms to automatically prune the registered listener interest graph that is used to keep track of subscribers, including slow consumers and lazy listeners. NATS automatically handles a slow consumer. If a client is not processing messages quick enough, the NATS server cuts it off. To support scaling, NATS provides for auto-pruning of client connections. If a subscriber does not respond to ping requests from the server within the [ping-pong interval](/documentation/internals/nats-protocol/), the client is cut off (disconnected). The client will need to have reconnect logic to reconnect with the server.
+
# Slow Consumers
In core NATS, consumers that cannot keep up are handled differently from many other messaging systems: NATS favors the approach of protecting the system as a whole over accommodating a particular consumer to ensure message delivery.
__What is a slow consumer?__
-A slow consumer is a subscriber that cannot keep up with the message flow delivered from the NATS server. This is a common case in distributed systems because it is often easier to generate data than it is to process it. When consumers cannot process data fast enough, back pressure is applied to the rest of the system. NATS has mechanisms to reduce this backpressure.
+A slow consumer is a subscriber that cannot keep up with the message flow delivered from the NATS server. This is a common case in distributed systems because it is often easier to generate data than it is to process it. When consumers cannot process data fast enough, back pressure is applied to the rest of the system. NATS has mechanisms to reduce this back pressure.
NATS identifies slow consumers in the client or the server, providing notification through registered callbacks, log messages, and statistics in the server's monitoring endpoints.
@@ -26,7 +28,7 @@ When detected at the client, the application is notified and messages are droppe
## Slow consumers identified in the client
-A client can detect it is a slow consumer on a local connection and notify the application through use of the asynchronous error callback. It is better to catch a slow consumer locally in the client rather than to allow the server to detect this condition. This example demonstrates how to define and register an asynchronous error handler that will handle slow consumer errors.
+A [client can detect it is a slow consumer](/doc/writing_applications/advanced#slow-consumers) on a local connection and notify the application through use of the asynchronous error callback. It is better to catch a slow consumer locally in the client rather than to allow the server to detect this condition. This example demonstrates how to define and register an asynchronous error handler that will handle slow consumer errors.
```go
func natsErrHandler(nc *nats.Conn, sub *nats.Subscription, natsErr error) {
@@ -50,7 +52,8 @@ nc, err := nats.Connect("nats://localhost:4222",
```
With this example code and default settings, a slow consumer error would generate output something like this:
-```
+
+```sh
error: nats: slow consumer, messages dropped
Falling behind with 65536 pending messages on subject "foo".
```
@@ -63,7 +66,7 @@ When a client does not process messages fast enough, the server will buffer mess
When the server initiates a slow consumer error, you'll see the following in the server output:
-```
+```sh
[54083] 2017/09/28 14:45:18.001357 [INF] ::1:63283 - cid:7 - Slow Consumer Detected
```
@@ -71,7 +74,7 @@ The server will also keep count of the number of slow consumer errors encountere
## Handling slow consumers
-Apart from using [NATS streaming](http://nats.io/documentation/streaming/nats-streaming-intro/) or optimizing your consuming application, there are a few options available: scale, meter, or tune NATS to your environment.
+Apart from using [NATS streaming](http://nats.io/doc/streaming/nats-streaming-intro/) or optimizing your consuming application, there are a few options available: scale, meter, or tune NATS to your environment.
__Scaling with queue subscribers__
@@ -96,11 +99,12 @@ The NATS server can be tuned to determine how much data can be buffered before a
The NATS server has a write deadline it uses to write to a connection. When this write deadline is exceeded, a client is considered to have a slow consumer. If you are encountering slow consumer errors in the server, you can increase the write deadline to buffer more data.
The `write_deadline` configuration option in the NATS server configuration file will tune this:
-```
+
+```ascii
write_deadline: 2s
```
- Tuning this parameter is ideal when you have bursts of data to accomodate. **_Be sure you are not just postponing a slow consumer error._**
+ Tuning this parameter is ideal when you have bursts of data to accommodate. **_Be sure you are not just postponing a slow consumer error._**
### Client Configuration
@@ -110,7 +114,7 @@ This buffer can be configured through setting the pending limits after a subscri
```go
if err := sub.SetPendingLimits(1024*500, 1024*5000); err != nil {
- log.Fatalf("Unable to set pending limits: %v", err)
+ log.Fatalf("Unable to set pending limits: %v", err)
}
```
diff --git a/content/documentation/server/gnatsd-top.md b/content/doc/managing_the_server/statistics.md
similarity index 92%
rename from content/documentation/server/gnatsd-top.md
rename to content/doc/managing_the_server/statistics.md
index 4db018cd..9ae19533 100644
--- a/content/documentation/server/gnatsd-top.md
+++ b/content/doc/managing_the_server/statistics.md
@@ -1,22 +1,19 @@
+++
-date = "2015-09-27"
-title = "Message Statistics"
+title = "Tracking NATS Statistics"
description = ""
category = "server"
[menu.main]
- name = "Message Statistics"
- weight = 10
- identifier = "server-gnatsd-top"
- parent = "Server"
+ name = "Statistics"
+ weight = 11
+ identifier = "doc-statistics"
+ parent = "Managing the Server"
+++
-# NATS Top for Message Statistics
-
[nats-top](https://github.com/nats-io/nats-top) is a [top](http://man7.org/linux/man-pages/man1/top.1.html)-like tool for monitoring gnatsd servers.
The nats-top tool provides a dynamic real-time view of a NATS server. nats-top can display a variety of system summary information about the NATS server, such as subscription, pending bytes, number of messages, and more, in real time. For example:
-```
+```sh
nats-top
gnatsd version 0.6.4 (uptime: 31m42s)
@@ -37,7 +34,7 @@ Connections: 4
nats-top can be installed using `go get`. For example:
-```
+```sh
go get github.com/nats-io/nats-top
```
@@ -47,7 +44,7 @@ NOTE: You may have to run the above command as user `sudo` depending on your set
Once installed, nats-top can be run with the command `nats-top` and optional arguments.
-```
+```sh
nats-top [-s server] [-m monitor] [-n num_connections] [-d delay_in_secs] [-sort by]
```
@@ -80,10 +77,14 @@ You can also set this on the command line using the `-n num_connections` flag. F
Note that if `n` is used in conjunction with `-sort`, the server will respect both options allowing queries such as the following: Query for the connection with largest number of subscriptions: `nats-top -n 1 -sort subs`.
-### Other
+### s, ? and q Commands
Use the `s` command to toggle displaying connection subscriptions.
Use the `?` command to show help message with options.
Use the `q` command to quit nats-top.
+
+### Tutorial
+
+For a walkthrough with `nats-top` check out the [tutorial](/doc/additional_documentation/nats-top).
\ No newline at end of file
diff --git a/content/documentation/streaming/nats-streaming-install.md b/content/doc/streaming/nats-streaming-install.md
similarity index 88%
rename from content/documentation/streaming/nats-streaming-install.md
rename to content/doc/streaming/nats-streaming-install.md
index 8c751960..aa0ac44d 100644
--- a/content/documentation/streaming/nats-streaming-install.md
+++ b/content/doc/streaming/nats-streaming-install.md
@@ -1,13 +1,13 @@
+++
date = "2015-09-27"
-title = "Install NATS Streaming Server"
+title = "Installing NATS Streaming Server"
description = ""
category = "tutorials"
[menu.main]
- name = "Install NATS Streaming Server"
+ name = "Installation"
weight = 2
- identifier = "tutorial-nats-streaming-install"
- parent = "Streaming"
+ identifier = "doc-streaming-installation"
+ parent = "Event Streaming"
+++
# Install and Run NATS Streaming Server
@@ -15,7 +15,6 @@ category = "tutorials"
In this tutorial you install and run the NATS Streaming server (`nats-streaming-server`).
You can follow this same procedure anytime you want to run the NATS Streaming server.
-
### Install the NATS Streaming server
There are numerous ways to install the NATS Streaming server.
@@ -25,9 +24,9 @@ There are numerous ways to install the NATS Streaming server.
The latest official release binaries are always available on the [GitHub releases page](https://github.com/nats-io/nats-streaming-server/releases).
The following platforms are available:
- * Linux (x86, x86_64, ARM)
- * Windows (x86, x86_64)
- * macOS
+- Linux (x86, x86_64, ARM)
+- Windows (x86, x86_64)
+- macOS
The following methods may also be used. _Please note that these methods may not install the latest released version_:
@@ -35,8 +34,8 @@ The following methods may also be used. _Please note that these methods may not
Make sure [your Go environment is set up](/documentation/tutorials/go-install/)
-```
-go get github.com/nats-io/nats-streaming-server
+```sh
+% go get github.com/nats-io/nats-streaming-server
```
Note that this method may not install the latest released version.
@@ -49,29 +48,29 @@ The latest [official Docker image](https://hub.docker.com/_/nats-streaming/) is
On Windows, the NATS Streaming server can also be installed via [Chocolatey](https://chocolatey.org/packages/nats-streaming-server):
-```
-choco install nats-streaming-server
+```sh
+% choco install nats-streaming-server
```
#### macOS
-On macOS, the NATS Streaming server can alo be installed via [Homebrew](http://brewformulas.org/NatsStreamingServer):
+On macOS, the NATS Streaming server can be installed via [Homebrew](http://brewformulas.org/NatsStreamingServer):
-```
-brew install nats-streaming-server
+```sh
+% brew install nats-streaming-server
```
### Start the NATS Streaming server
You can invoke the NATS Streaming server binary, with no options and no configuration file, to start a server with acceptable standalone defaults (no authentication, no clustering).
-```
-nats-streaming-server
+```sh
+% nats-streaming-server
```
When the server starts successfully, you will see that the NATS Streaming server listens for client connections on TCP Port 4222:
-```
+```sh
[18085] 2016/10/31 13:11:44.059012 [INF] Starting nats-streaming-server[test-cluster] version 0.3.1
[18085] 2016/10/31 13:11:44.059830 [INF] Starting nats-server version 0.9.4
[18085] 2016/10/31 13:11:44.061544 [INF] Listening for client connections on 0.0.0.0:4222
@@ -91,13 +90,13 @@ When the server starts successfully, you will see that the NATS Streaming server
The NATS Streaming server exposes the monitoring interface of its embedded NATS Server (`gnatsd`) on port 8222.
-```
-nats-streaming-server -m 8222
+```sh
+% nats-streaming-server -m 8222
```
If you run the NATS Streaming server with monitoring enabled, you see the following messages:
-```
+```sh
[18122] 2016/10/31 13:13:10.048663 [INF] Starting nats-streaming-server[test-cluster] version 0.3.1
[18122] 2016/10/31 13:13:10.048843 [INF] Starting nats-server version 0.9.4
[18122] 2016/10/31 13:13:10.048890 [INF] Starting http monitor on 0.0.0.0:8222
diff --git a/content/documentation/streaming/nats-streaming-intro.md b/content/doc/streaming/nats-streaming-intro.md
similarity index 78%
rename from content/documentation/streaming/nats-streaming-intro.md
rename to content/doc/streaming/nats-streaming-intro.md
index de6ed021..07c6b99e 100644
--- a/content/documentation/streaming/nats-streaming-intro.md
+++ b/content/doc/streaming/nats-streaming-intro.md
@@ -1,32 +1,54 @@
+++
date = "2015-06-17"
-title = "NATS Streaming"
+title = "NATS Streaming Concepts"
description = ""
category = "server"
[menu.main]
- name = "NATS Streaming"
+ name = "Concepts"
weight = 1
- identifier = "streaming-nats-streaming-intro"
- parent = "Streaming"
+ identifier = "doc-streaming-intro"
+ parent = "Event Streaming"
+++
-# NATS Streaming
-
NATS Streaming is a data streaming system powered by NATS, and written in the Go programming language. The executable name for the NATS Streaming server is `nats-streaming-server`. NATS Streaming embeds, extends, and interoperates seamlessly with the core NATS platform. The [NATS Streaming server](https://github.com/nats-io/nats-streaming-server) is provided as open source software under the Apache-2.0 license. Synadia actively maintains and supports the NATS Streaming server.
-
+
## Features
In addition to the features of the core NATS platform, NATS Streaming provides the following:
-- **Enhanced message protocol** - NATS Streaming implements its own enhanced message format using [Google Protocol Buffers] (https://developers.google.com/protocol-buffers/). These messages are transmitted as binary message paylods via core NATS platform, and thus require no changes to the basic NATS protocol. NATS Streaming messages contain the following fields:
+- **Enhanced message protocol** - NATS Streaming implements its own enhanced message format using [Google Protocol Buffers] (https://developers.google.com/protocol-buffers/). These messages are transmitted as binary message payloads via core NATS platform, and thus require no changes to the basic NATS protocol. NATS Streaming messages contain the following fields:
- Sequence - a globally ordered sequence number for the subject's channel
- Subject - The NATS Streaming delivery subject
- Reply - The optional "reply-to" subject
- Data - The message payload
- Timestamp - the received timestamp, in nanoseconds.
- - Redelivered - A flag signifiying whether this message has been redelivered by the server
+ - Redelivered - A flag signifying whether this message has been redelivered by the server
- CRC32 - An optional IEEE CRC32
- **Message/event persistence** - NATS Streaming offers configurable message persistence either in-memory or via flat files. The storage subsystem uses a public interface that allows contributors to develop their own custom implementations.
- **At-least-once-delivery** - NATS Streaming offers message acknowledgements between publisher and server (for publish operations) and between subscriber and server (to confirm message delivery). Messages are persisted by the server in memory or secondary storage (or other external storage) and will be redelivered to eligible subscribing clients as needed.
diff --git a/content/documentation/streaming/nats-streaming-protocol.md b/content/doc/streaming/nats-streaming-protocol.md
similarity index 64%
rename from content/documentation/streaming/nats-streaming-protocol.md
rename to content/doc/streaming/nats-streaming-protocol.md
index 2c4495b4..dde15cf2 100644
--- a/content/documentation/streaming/nats-streaming-protocol.md
+++ b/content/doc/streaming/nats-streaming-protocol.md
@@ -3,15 +3,13 @@ date = "2016-07-15"
title = "NATS Streaming Protocol"
category = "internals"
[menu.main]
- name = "NATS Streaming Protocol"
- weight = 2
- identifier = "internals-nats-streaming-protocol"
- parent = "Streaming"
+ name = "Streaming Protocol"
+ weight = 5
+ identifier = "doc-streaming-protocol"
+ parent = "Event Streaming"
+++
-# NATS streaming protocol
-
-The NATS streaming protocol sits atop the core [NATS protocol](/documentation/internals/nats-protocol) and uses [Google's Protocol Buffers](https://developers.google.com/protocol-buffers/). Protocol buffer messages are marshalled into bytes and published as NATS messages on specific subjects described below. In communicating with the NATS Streaming Server, the NATS [request/reply](/documentation/concepts/nats-req-rep) pattern is used for all protocol messages that have a corresponding reply.
+The NATS streaming protocol sits atop the core [NATS protocol](/doc/internals/nats-protocol) and uses [Google's Protocol Buffers](https://developers.google.com/protocol-buffers/). Protocol buffer messages are marshaled into bytes and published as NATS messages on specific subjects described below. In communicating with the NATS Streaming Server, the NATS [request/reply](/doc/writing_applications/concepts) pattern is used for all protocol messages that have a corresponding reply.
## NATS streaming protocol conventions
@@ -19,9 +17,9 @@ The NATS streaming protocol sits atop the core [NATS protocol](/documentation/in
`FOO`, `BAR`, `foo.bar`, `foo.BAR`, `FOO.BAR` and `FOO.BAR.BAZ` are all valid subject names
-`FOO. BAR`, `foo. .bar` and`foo..bar` are *not* valid subject names
+`FOO. BAR`, `foo. .bar` and`foo..bar` are *not- valid subject names
-**Wildcards**: NATS streaming does **not** support wildcards in subject subscriptions
+**Wildcards**: NATS streaming does **not*- support wildcards in subject subscriptions
**Protocol definition**: The fields of NATS streaming protocol messages are defined in the go-nats-streaming [protocol file](https://github.com/nats-io/go-nats-streaming/blob/master/pb/protocol.proto).
@@ -49,150 +47,152 @@ The following sections explain each protocol message.
## ConnectRequest
-### Message Structure
+#### Description
-* `clientID`: A unique identifier for a client
-* `heartbeatInbox`: An inbox to which the NATS Streaming Server will send heartbeats for the client to process
+A connection request is sent when a streaming client connects to the NATS Streaming Server. The connection request contains a unique identifier representing the client, and an inbox subject the client will listen on for incoming heartbeats. The identifier **must*- be unique; a connection attempt with an identifier currently in use will fail. The inbox subject is the subject where the client receives incoming heartbeats, and responds by publishing an empty NATS message to the reply subject, indicating it is alive. The NATS Streaming Server will return a [ConnectResponse](#CONNRESP) message to the reply subject specified in the NATS request message.
-### Description
+This request is published to a subject comprised of the `.cluster-id`, for example, if a NATS Streaming Server was started with a cluster-id of `mycluster`, and the default prefix was used, the client publishes to `_STAN.discover.mycluster`
-A connection request is sent when a streaming client connects to the NATS Streaming Server. The connection request contains a unique identifier representing the client, and an inbox subject the client will listen on for incoming heartbeats. The identifier **must** be unique; a connection attempt with an identifier currently in use will fail. The inbox subject is the subject where the client receives incoming heartbeats, and responds by publishing an empty NATS message to the reply subject, indicating it is alive. The NATS Streaming Server will return a [ConnectResponse](#CONNRESP) message to the reply subject specified in the NATS request message.
+#### Message Structure
-This request is published to a subject comprised of the `.cluster-id`, for example, if a NATS Streaming Server was started with a cluster-id of `mycluster`, and the default prefix was used, the client publishes to `_STAN.discover.mycluster`
+- `clientID`: A unique identifier for a client
+- `heartbeatInbox`: An inbox to which the NATS Streaming Server will send heartbeats for the client to process
## ConnectResponse
-### Message Structure
-
-* `pubPrefix`: Prefix to use when publishing
-* `subRequests`: Subject used for subscription requests
-* `unsubRequests`: Subject used for unsubscribe requests
-* `closeRequests`: Subject for closing a connection
-* `error`: An error string, which will be empty/omitted upon success
-* `publicKey`: Reserved for future use
+#### Description
-### Description
After a `ConnectRequest` is published, the NATS Streaming Server responds with this message on the reply subject of the underlying NATS request. The NATS Streaming Server requires the client to make requests and publish messages on certain subjects (described above), and when a connection is successful, the client saves the information returned to be used in sending other NATS streaming protocol messages. In the event the connection was not successful, an error is returned in the `error` field.
-## SubscriptionRequest
-
-### Message Structure
+#### Message Structure
-* `clientID`: Client ID originally provided in the [ConnectRequest](#CONNREQ)
-* `subject`: Formal subject to subscribe to, e.g. foo.bar
-* `qGroup`: Optional queue group
-* `inbox`: Inbox subject to deliver messages on
-* `maxInFlight`: Maximum inflight messages without an acknowledgement allowed
-* `ackWaitInSecs`: Timeout for receiving an acknowledgement from the client
-* `durableName`: Optional durable name which survives client restarts
-* `startPosition`: An enumerated type specifying the point in history to start replaying data
-* `startSequence`: Optional start sequence number
-* `startTimeDelta`: Optional start time
+- `pubPrefix`: Prefix to use when publishing
+- `subRequests`: Subject used for subscription requests
+- `unsubRequests`: Subject used for unsubscribe requests
+- `closeRequests`: Subject for closing a connection
+- `error`: An error string, which will be empty/omitted upon success
+- `publicKey`: Reserved for future use
-StartPosition enumeration
+## SubscriptionRequest
-* `NewOnly`: Send only new messages
-* `LastReceived`: Send only the last received message
-* `TimeDeltaStart`: Send messages from duration specified in the `startTimeDelta` field.
-* `SequenceStart`: Send messages starting from the sequence in the `startSequence` field.
-* `First`: Send all available messages
+#### Description
-### Description
A `SubscriptionRequest` is published on the subject returned in the `subRequests` field of a [`ConnectResponse`](#CONNRESP), and creates a subscription to a subject on the NATS Streaming Server. The will return a [SubscriptionResponse](#SUBRESP) message to the reply subject specified in the NATS protocol request message.
-## SubscriptionResponse
-
#### Message Structure
-* `ackInbox`: subject the client sends message acknowledgements to the NATS Streaming Server
-* `error`: error string, empty/omitted if no error
+- `clientID`: Client ID originally provided in the [ConnectRequest](#CONNREQ)
+- `subject`: Formal subject to subscribe to, e.g. foo.bar
+- `qGroup`: Optional queue group
+- `inbox`: Inbox subject to deliver messages on
+- `maxInFlight`: Maximum inflight messages without an acknowledgement allowed
+- `ackWaitInSecs`: Timeout for receiving an acknowledgement from the client
+- `durableName`: Optional durable name which survives client restarts
+- `startPosition`: An enumerated type specifying the point in history to start replaying data
+- `startSequence`: Optional start sequence number
+- `startTimeDelta`: Optional start time
+
+#### StartPosition enumeration
+
+- `NewOnly`: Send only new messages
+- `LastReceived`: Send only the last received message
+- `TimeDeltaStart`: Send messages from duration specified in the `startTimeDelta` field.
+- `SequenceStart`: Send messages starting from the sequence in the `startSequence` field.
+- `First`: Send all available messages
-### Description
+## SubscriptionResponse
+
+#### Description
The `SubscriptionResponse` message is the response from the `SubscriptionRequest`. After a client has processed an incoming [MsgProto](#MSGPROTO) message, it must send an acknowledgement to the `ackInbox` subject provided here.
-## UnsubscribeRequest
+#### Message Structure
-### Message Structure
+- `ackInbox`: subject the client sends message acknowledgements to the NATS Streaming Server
+- `error`: error string, empty/omitted if no error
-* `clientID`: Client ID originally provided in the [ConnectRequest](#CONNREQ)
-* `subject`: Subject for the subscription
-* `inbox`: Inbox subject to identify subscription
-* `durableName`: Optional durable name which survives client restarts
+## UnsubscribeRequest
-### Description
+#### Description
The `UnsubscribeRequest` unsubcribes the connection from the specified subject. The inbox specified is the `inbox` returned from the NATS Streaming Server in the `SubscriptionResponse`.
-## PubMsg
+#### Message Structure
-### Message Structure
+- `clientID`: Client ID originally provided in the [ConnectRequest](#CONNREQ)
+- `subject`: Subject for the subscription
+- `inbox`: Inbox subject to identify subscription
+- `durableName`: Optional durable name which survives client restarts
-* `clientID`: Client ID originally provided in the [ConnectRequest](#CONNREQ)
-* `guid`: a guid generated for this particular message
-* `subject`: subject
-* `reply`: optional reply subject
-* `data`: payload
-* `sha256`: optional sha256 of payload data
+## PubMsg
-### Description
+#### Description
The `PubMsg` protocol message is published from a client to the NATS Streaming Server. The GUID must be unique, and is returned in the [PubAck](#PUBACK) message to correlate the success or failure of storing this particular message.
-## PubAck
+#### Message Structure
-### Message Structure
+- `clientID`: Client ID originally provided in the [ConnectRequest](#CONNREQ)
+- `guid`: a guid generated for this particular message
+- `subject`: subject
+- `reply`: optional reply subject
+- `data`: payload
+- `sha256`: optional sha256 of payload data
-* `guid`: GUID of the message being acknowledged by the NATS Streaming Server
-* `error`: An error string, empty/omitted if no error
+## PubAck
-### Description
+#### Description
The `PubAck` message is an acknowledgement from the NATS Streaming Server that a message has been processed. The message arrives on the subject specified on the reply subject of the NATS message the `PubMsg` was published on. The GUID is the same GUID used in the `PubMsg` being acknowledged. If an error string is present, the message was not persisted by the NATS Streaming Server and no guarantees regarding persistence are honored. `PubAck` messages may be handled asynchronously from their corresponding `PubMsg` in the client.
-## MsgProto
+#### Message Structure
-### Message Structure
+- `guid`: GUID of the message being acknowledged by the NATS Streaming Server
+- `error`: An error string, empty/omitted if no error
-* `sequence`: Globally ordered sequence number for the subject's channel
-* `subject`: Subject
-* `reply`: Optional reply
-* `data`: Payload
-* `timestamp`: Time the message was stored in the server.
-* `redelivered`: Flag specifying if the message is being redelivered
-* `CRC32`: Optional IEEE CRC32
+## MsgProto
-### Description
+#### Description
The `MsgProto` message is received by client from the NATS Streaming Server, containing the payload of messages sent by a publisher. A `MsgProto` message that is not acknowledged with an [Ack](#ACK) message within the duration specified by the `ackWaitInSecs` field of the subscription request will be redelivered.
-## Ack
+#### Message Structure
-### Message Structure
+- `sequence`: Globally ordered sequence number for the subject's channel
+- `subject`: Subject
+- `reply`: Optional reply
+- `data`: Payload
+- `timestamp`: Time the message was stored in the server.
+- `redelivered`: Flag specifying if the message is being redelivered
+- `CRC32`: Optional IEEE CRC32
-* `subject`: Subject of the message being acknowledged
-* `sequence`: Sequence of the message being acknowledged
+## Ack
-### Description
+#### Description
An `Ack` message is an acknowledgement from the client that a [MsgProto](#MSGPROTO) message has been considered received. It is published to the `ackInbox` field of the [`SubscriptionResponse`](#SUBRESP).
+#### Message Structure
+
+- `subject`: Subject of the message being acknowledged
+- `sequence`: Sequence of the message being acknowledged
+
## CloseRequest
-### Message Structure
+#### Description
-* `clientID`: Client ID originally provided in the [ConnectRequest](#CONNREQ)
+A `CloseRequest` message is published on the `closeRequests` subject from the [`ConnectResponse`](#CONNRESP), and notifies the NATS Streaming Server that the client connection is closing, allowing the server to free up resources. This message should **always*- be sent when a client is finished using a connection.
-### Description
+#### Message Structure
-A `CloseRequest` message is published on the `closeRequests` subject from the [`ConnectResponse`](#CONNRESP), and notifies the NATS Streaming Server that the client connection is closing, allowing the server to free up resources. This message should **always** be sent when a client is finished using a connection.
+- `clientID`: Client ID originally provided in the [ConnectRequest](#CONNREQ)
## CloseResponse
-### Message Structure
+#### Description
-* `error`: error string, empty/omitted if no error
+The `CloseResponse` is sent by the NATS Streaming Server on the reply subject of the `CloseRequest` NATS message. This response contains any error that may have occurred with the corresponding close call.
-### Description
+#### Message Structure
-The `CloseResponse` is sent by the NATS Streaming Server on the reply subject of the `CloseRequest` NATS message. This response contains any error that may have occurred with the corresponding close call.
+- `error`: error string, empty/omitted if no error
diff --git a/content/documentation/streaming/nats-streaming-quickstart.md b/content/doc/streaming/nats-streaming-quickstart.md
similarity index 77%
rename from content/documentation/streaming/nats-streaming-quickstart.md
rename to content/doc/streaming/nats-streaming-quickstart.md
index 5562cfa6..5a6f4029 100644
--- a/content/documentation/streaming/nats-streaming-quickstart.md
+++ b/content/doc/streaming/nats-streaming-quickstart.md
@@ -4,22 +4,20 @@ title = "Getting Started with NATS Streaming"
description = ""
category = "tutorials"
[menu.main]
- name = "Getting Started with NATS Streaming"
- weight = 9
- identifier = "tutorial-nats-streaming"
- parent = "Streaming"
+ name = "Getting Started"
+ weight = 3
+ identifier = "tutorial-nats-streaming-1"
+ parent = "Event Streaming"
+++
-# Getting Started with NATS Streaming
-
This tutorial demonstrates NATS Streaming using example [Go NATS Streaming clients](https://github.com/nats-io/go-nats-streaming.git).
-**Prerequisites**
+## Prerequisites
- [Set up your Git environment](https://help.github.com/articles/set-up-git/).
- [Set up your Go environment](https://golang.org/doc/install).
-**Setup**
+## Setup
Download and install the [NATS Streaming Server](https://github.com/nats-io/nats-streaming-server/releases).
@@ -28,7 +26,7 @@ Clone the following repositories:
- NATS Streaming Server: `git clone https://github.com/nats-io/nats-streaming-server.git`
- NATS Streaming Client: `git clone https://github.com/nats-io/go-nats-streaming.git`
-**Start the NATS Streaming Server**
+## Start the NATS Streaming Server
Two options:
@@ -36,15 +34,15 @@ Run the binary that you downloaded, for example: `$ ./nats-streaming-server`
Or, run from source:
-```
-$ cd $GOPATH/src/github.com/nats-io/nats-streaming-server
-$ go run nats-streaming-server.go
+```sh
+% cd $GOPATH/src/github.com/nats-io/nats-streaming-server
+% go run nats-streaming-server.go
```
You should see the following, indicating that the NATS Streaming Server is running:
-```
-go run nats-streaming-server.go
+```sh
+% go run nats-streaming-server.go
[89999] 2016/06/25 08:54:35.399071 [INF] Starting nats-streaming-server[test-cluster] version 0.1.0
[89999] 2016/06/25 08:54:35.399315 [INF] Starting nats-server version 0.9.0.beta
[89999] 2016/06/25 08:54:35.399326 [INF] Listening for client connections on localhost:4222
@@ -53,28 +51,27 @@ go run nats-streaming-server.go
[89999] 2016/06/25 08:54:35.737610 [INF] STAN: Maximum of 1000000 will be stored
```
-**Run the publisher client**
+## Run the publisher client
Publish several messages. For each publication you should get a result.
-```
-$ cd $GOPATH/src/github.com/nats-io/go-nats-streaming/examples/stan-pub
-$ go run main.go foo "msg one"
+```sh
+% cd $GOPATH/src/github.com/nats-io/go-nats-streaming/examples/stan-pub
+% go run main.go foo "msg one"
Published [foo] : 'msg one'
-$ go run main.go foo "msg two"
+% go run main.go foo "msg two"
Published [foo] : 'msg two'
-$ go run main.go foo "msg three"
+% go run main.go foo "msg three"
Published [foo] : 'msg three'
-$
```
-**Run the subscriber client**
+## Run the subscriber client
Use the `--all` flag to receive all published messages.
-```
-$ cd $GOPATH/src/github.com/nats-io/go-nats-streaming/examples/stan-sub
-$ go run main.go --all -c test-cluster -id myID foo
+```sh
+% cd $GOPATH/src/github.com/nats-io/go-nats-streaming/examples/stan-sub
+% go run main.go --all -c test-cluster -id myID foo
Connected to nats://localhost:4222 clusterID: [test-cluster] clientID: [myID]
subscribing with DeliverAllAvailable
Listening on [foo], clientID=[myID], qgroup=[] durable=[]
@@ -83,9 +80,9 @@ Listening on [foo], clientID=[myID], qgroup=[] durable=[]
[#3] Received on [foo]: 'sequence:3 subject:"foo" data:"msg three" timestamp:1465962215567601196
```
-**Explore other subscription options**
+## Explore other subscription options
-```
+```sh
--seq Start at seqno
--all Deliver all available messages
--last Deliver starting with last published message
diff --git a/content/documentation/streaming/nats-streaming-tls.md b/content/doc/streaming/nats-streaming-tls.md
similarity index 72%
rename from content/documentation/streaming/nats-streaming-tls.md
rename to content/doc/streaming/nats-streaming-tls.md
index cdeb974e..d177eae9 100644
--- a/content/documentation/streaming/nats-streaming-tls.md
+++ b/content/doc/streaming/nats-streaming-tls.md
@@ -4,14 +4,12 @@ title = "Securing NATS Streaming Server"
description = ""
category = "server"
[menu.main]
- name = "Securing NATS Streaming Server"
- weight = 3
- identifier = "streaming-nats-streaming-security"
- parent = "Streaming"
+ name = "Security"
+ weight = 4
+ identifier = "doc-streaming-security"
+ parent = "Event Streaming"
+++
-This section describes how to secure the NATS Streaming Server, including user authentication and TLS certificates.
-
## Authenticating users
To enable user authentication from the command line, you can use the same mechanism as the NATS Server (`gnatsd`). You pass in the `—user ` and `—pass ` commands, or `--auth` parameters, and the NATS streaming server will automatically use these credentials. Or you can use a configuration file with a single user or token.
@@ -28,24 +26,20 @@ That means two sets of TLS configuration parameters must be used: TLS server par
The streaming server specifies it's TLS client certificates with the following three parameters:
-```
- -tls_client_key Client key for the streaming server
-
- -tls_client_cert Client certificate for the streaming server
-
- -tls_client_cacert Client certificate CA for the streaming server
+```sh
+-tls_client_key Client key for the streaming server
+-tls_client_cert Client certificate for the streaming server
+-tls_client_cacert Client certificate CA for the streaming server
```
These could be the same certificates used with your NATS streaming clients.
The embedded NATS server specifies TLS server certificates with these:
-```
- --tlscert Server certificate file
-
- --tlskey Private key for server certificate
-
- --tlscacert Client certificate CA for verification
+```sh
+--tlscert Server certificate file
+--tlskey Private key for server certificate
+--tlscacert Client certificate CA for verification
```
The server parameters are used the same way you'd [secure a typical NATS server]((https://github.com/nats-io/gnatsd#securing-nats).
@@ -54,8 +48,8 @@ Proper usage of the NATS Streaming Server requires the use of both client and se
For example:
-```
-nats-streaming-server -tls_client_cert client-cert.pem -tls_client_key client-key.pem -tls_client_cacert ca.pem -tlscert server-cert.pem -tlskey server-key.pem -tlscacert ca.pem
+```sh
+% nats-streaming-server -tls_client_cert client-cert.pem -tls_client_key client-key.pem -tls_client_cacert ca.pem -tlscert server-cert.pem -tlskey server-key.pem -tlscacert ca.pem
```
Further TLS related functionality can be found in [Securing NATS > TLS](https://github.com/nats-io/gnatsd#securing-nats). Note that if specifying cipher suites is required, a configuration file for the embedded NATS server can be passed through the `-config` command line parameter.
diff --git a/content/doc/writing_applications/advanced.md b/content/doc/writing_applications/advanced.md
new file mode 100644
index 00000000..b5f8cb5e
--- /dev/null
+++ b/content/doc/writing_applications/advanced.md
@@ -0,0 +1,63 @@
++++
+category = "api"
+title = "Advanced Topics"
+[menu.main]
+ name = "Advanced Topics"
+ weight = 8
+ identifier = "doc-advanced-topics"
+ parent = "Writing Applications"
++++
+
+Managing the interaction with the server is primarily the job of the client library but most of the libraries also provide some insight into what is happening under the covers.
+
+### Get the Current Server Status
+
+The client library may provide a mechanism to get the connections current status.
+
+{{< partial "doc/connect_status.html" >}}
+
+### Listen for Connection Events
+
+While the status is interesting, it is perhaps more interesting to know when the status changes. Most, if not all, of the NATS client libraries provide a way to listen for events related to the connection and its status. The actual API for these listeners is language dependent, but the following examples show a few of the more common use cases. See the API documentation for the client library you are using for more specific instructions. Connection events may include the connection being closed, disconnected or reconnected. Reconnecting involves a disconnect and connect, but depending on the library implementation may also include multiple disconnects as the client tries to find a server, or the server is rebooted.
+
+{{< partial "doc/connection_listener.html" >}}
+
+### Listen for New Servers
+
+When working with a cluster, servers may be added or changed. Some of the clients allow you to listen for this notification:
+
+{{< partial "doc/servers_added.html" >}}
+
+### Listen for Errors
+
+The client library may separate server-to-client errors from events. Many server events are not handled by application code and result in the connection being closed. Listening for the errors can be very useful for debugging problems.
+
+{{< partial "doc/error_listener.html" >}}
+
+## Slow Consumers
+
+NATS is designed to move messages through the server quickly. As a result, NATS depends on the applications to consider and respond to changing message rates. The server will do a bit of impedance matching, but if a client is too slow the server will eventually cut them off. One way some of the libraries deal with bursty message traffic is to cache incoming messages for a subscription. So if an application can handle 10 messages per second and sometimes receives 20 messages per second, the library may hold the extra 10 to give the application time to catch up. To the server, the application will appear to be handling the messages and consider the connection healthy. It is up to the client library to decide what to do when the cache is too big, but most client libraries will drop incoming messages.
+
+Receiving and dropping messages from the server keeps the connection to the server healthy, but creates an application requirement. There are several common patterns:
+
+* Use request/reply to throttle the sender and prevent overloading the subscriber
+* Use a queue with multiple subscribers splitting the work
+* Persist/cache messages with something like NATS streaming
+
+Libraries that cache incoming messages may provide two controls on the incoming queue, or pending messages. These are useful if the problem is bursty publishers and not a continuous performance mismatch. Disabling these limits can be dangerous in production and although setting these limits to 0 may help find problems, it is also a dangerous proposition in production.
+
+> Check your libraries documentation for the default settings, and support for disabling these limits.
+
+The incoming cache is usually per subscriber, but again, check the specific documentation for your client library.
+
+### Limiting Incoming/Pending Messages by Count and Bytes
+
+The first way that the incoming queue can be limited is by message count. The second way to limit the incoming queue is by total size. For example, to limit the incoming cache to 1,000 messages or 5mb whichever comes first:
+
+{{< partial "doc/slow_pending_limits.html" >}}
+
+### Detect a Slow Consumer and Check for Dropped Messages
+
+When a slow consumer is detected and messages are about to be dropped, the library may notify the application. This process may be similar to other errors or may involve a custom callback. Some libraries, like Java, will not send this notification on every dropped message because that could be noisy. Rather the notification may be sent once per time the subscriber gets behind. Libraries may also provide a way to get a count of dropped messages so that applications can at least detect a problem is occurring.
+
+{{< partial "doc/slow_listener.html" >}}
\ No newline at end of file
diff --git a/content/doc/writing_applications/concepts.md b/content/doc/writing_applications/concepts.md
new file mode 100644
index 00000000..57d96938
--- /dev/null
+++ b/content/doc/writing_applications/concepts.md
@@ -0,0 +1,129 @@
++++
+title = "NATS Messaging Concepts"
+category = "concepts"
+[menu.main]
+ name = "Concepts"
+ weight = 1
+ identifier = "doc-concepts"
+ parent = "Writing Applications"
++++
+
+NATS messaging involves the electronic exchange of data among computer applications and provides a layer between the application and the underlying physical network. Application data is encoded as a message and sent by a publisher. The message is received, decoded, and processed by one or more subscribers. A subscriber can process a NATS message synchronously or asynchronously, depending on the client library used.
+
+## Asynchronous
+
+Asynchronous processing uses a callback message handler to process messages. When a message arrives, the registered callback handler receives control to process the message. The client or the consuming application is not blocked from performing other work while it is waiting for a message. Asynchronous processing lets you create multi-threaded dispatching designs.
+
+## Synchronous
+
+Synchronous processing requires that application code explicitly call a method to process an incoming message. Typically the message request is a blocking call that suspends processing until a message becomes available and if no message is available, the period for which the message processing call blocks, would be set by the client. Synchronous processing is typically used by a server whose purpose is to wait for and process incoming request messages and to send replies to the requesting application.
+
+
+
+NATS makes it easy for programs to communicate across different environments, languages, and systems because all a client has to do is parse the message. NATS lets programs share common message-handling code, isolate resources and interdependencies, and scale by easily handling an increase in message volume.
+
+## Publish Subscribe
+
+NATS implements a publish subscribe message distribution model as a one-to-many communication. A publisher sends a message on a subject and any active subscriber listening on that subject receives the message. Subscribers can also register interest in wildcard subjects. NATS and NATS Streaming combine to offer two qualities of service:
+
+- **At Most Once Delivery (NATS w/TCP reliability)** - In the basic NATS platform, if a subscriber is not listening on the subject (no subject match), or is not active when the message is sent, the message is not received. NATS is a fire-and-forget messaging system. If you need higher levels of service, you can either use [NATS Streaming](/documentation/streaming/nats-streaming-intro/), or build the additional reliability into your client(s) yourself.
+
+- **At Least Once Delivery ([NATS Streaming](/documentation/streaming/nats-streaming-intro/))** - Some applications require higher levels of service and more stringent delivery guarantees but at the potential cost of lower message throughput and higher end-to-end delivery latency. These applications rely on the underlying messaging transport to ensure that messages are delivered to subscribers irrespective of network outages or whether or not a subscriber is offline at a particular point in time.
+
+
+
+Try NATS publish subscribe on your own, using a live server by walking through the [pub-sub tutorial](/doc/additional_documentation/nats-pub-sub).
+
+## Request Reply
+
+NATS supports two flavors of request reply messaging: point-to-point or one-to-many. Point-to-point involves the fastest or first to respond. In a one-to-many exchange, you set a limit on the number of responses the requestor may receive.
+
+In a request-response exchange, publish request operation publishes a message with a reply subject expecting a response on that reply subject. You can request to automatically wait for a response inline.
+
+The request creates an inbox and performs a request call with the inbox reply and returns the first reply received. This is optimized in the case of multiple responses.
+
+
+
+Try NATS request reply on your own, using a live server by walking through the [request/reply tutorial](/doc/additional_documentation/nats-req-rep).
+
+## Queue Subscribers & Sharing Work
+
+NATS provides a load balancing feature called queue subscriptions. Using queue subscribers will load balance message delivery across a group of subscribers which can be used to provide application fault tolerance and scale workload processing.
+
+To create a queue subscription, subscribers register a queue name. All subscribers with the same queue name form the queue group. As messages on the registered subject are published, one member of the group is chosen randomly to receive the message. Although queue groups have multiple subscribers, each message is consumed by only one.
+
+Queue subscribers can be asynchronous, in which case the message handler callback function processes the delivered message. Synchronous queue subscribers must build in logic to process the message. Queue subscribers are ideal for auto scaling as you can add or remove them anytime, without any configuration changes or restarting the server or clients.
+
+
+
+Try NATS queue subscriptions on your own, using a live server by walking through the [queueing tutorial](/doc/additional_documentation/nats-queueing).
\ No newline at end of file
diff --git a/content/doc/writing_applications/connecting.md b/content/doc/writing_applications/connecting.md
new file mode 100644
index 00000000..df891a09
--- /dev/null
+++ b/content/doc/writing_applications/connecting.md
@@ -0,0 +1,87 @@
++++
+category = "api"
+title = "Connecting to NATS"
+[menu.main]
+ name = "Connecting/Reconnecting"
+ weight = 3
+ identifier = "doc-connecting-to-nats"
+ parent = "Writing Applications"
++++
+
+Most client libraries provide several ways to connect to the NATS server, gnatsd. The server itself is identified by a standard URL with the `nats` protocol. Throughout these examples we will rely on a test server, provided by [nats.io](https://nats.io), at `nats://demo.nats.io:4222`, where `4222` is the default port for NATS.
+
+### Connecting to a Specific Server
+
+For example, to connect to the demo server with a URL:
+
+{{< partial "doc/connect_url.html" >}}
+
+### Connecting to the Default Server
+
+Some libraries also provide a special way to connect to a *default* url, which is general `nats://localhost:4222`:
+
+{{< partial "doc/connect_default.html" >}}
+
+### Setting a Connect Timeout
+
+Each library has its own, language preferred way, to pass connection options. For example, to set the maximum time to connect to a server to 10 seconds:
+
+{{< partial "doc/connect_options.html" >}}
+
+The available options are discussed more below, in other pages, and in the documentation for your client library.
+
+## Connecting to a Cluster
+
+When connecting to a cluster, there are a few things to think about.
+
+* Passing a URL for each cluster member (semi-optional)
+* The connection algorithm
+* The reconnect algorithm (discussed later)
+* Server provided URLs
+
+When a client connects to the server, the server may provide a list of URLs for additional known servers. This allows a client to connect to one server and still have other servers available during reconnect. However, the initial connection cannot depend on these additional servers. Rather, the additional connection will try to connect to each of the URLs provided in the connect call and will fail if it is unable to connect to any of them. *Note, failure behavior is library dependent, please check the documentation for your client library on information about what happens if the connect fails.*
+
+{{< partial "doc/connect_multiple.html" >}}
+
+## Reconnecting
+
+Most, if not all, of the client libraries will reconnect to the server if they are disconnected due to a network problem. The reconnect logic can differ by library, so check your client libraries. In general, the client will try to connect to all of the servers it knows about, either through the URLs provided in `connect` or the URLs provided by its most recent server. The library may have several options to help control reconnect behavior.
+
+### Disable Reconnect
+
+For example, you can disable reconnect:
+
+{{< partial "doc/reconnect_none.html" >}}
+
+### Set the Number of Reconnect Attempts
+
+Applications can set the maximum reconnect attempts. Generally, this will limit the actual number of attempts total, but check your library documentation. For example, in Java, if the client knows about 3 servers and the maximum reconnects is set to 2, it will not try all of the servers. On the other hand, if the maximum is set to 6 it will try all of the servers twice before considering the reconnect a failure and closing.
+
+{{< partial "doc/reconnect_10x.html" >}}
+
+### Pausing Between Reconnect Attempts
+
+It doesn’t make much sense to try to connect to the same server over and over. To prevent this sort of thrashing, and wasted reconnect attempts, libraries provide a wait setting. This setting will pause the reconnect logic if the same server is being tried multiple times. In the previous example, if you have 3 servers and 6 attempts, the Java library would loop over the three servers. If none were connectable, it will then try all three again. However, the Java client doesn’t wait between each attempt, only when trying the same server again, so in that example the library may never wait. If on the other hand, you only provide a single server URL and 6 attempts, the library will wait between each attempt.
+
+{{< partial "doc/reconnect_10s.html" >}}
+
+### Avoiding the Thundering Herd
+
+When a server goes down, there is a possible anti-pattern called the *Thundering Herd* where all of the clients try to reconnect immediately creating a denial of service attack. In order to prevent this, most NATS client libraries randomize the servers they attempt to connect to. This setting has no effect if only a single server is used, but in the case of a cluster, randomization, or shuffling, will ensure that no one server bears the brunt of the client reconnect attempts.
+
+{{< partial "doc/reconnect_no_random.html" >}}
+
+### Listening for Reconnect Events
+
+Because reconnect is primarily under the covers many libraries provide an event listener you can use to be notified of reconnect events. This event can be especially important for applications sending a lot of messages.
+
+{{< partial "doc/reconnect_event.html" >}}
+
+
+### Buffering Messages During Reconnect Attempts
+
+There is another setting that comes in to play during reconnection. This setting controls how much memory the client library will hold in the form of outgoing messages while it is disconnected. During a short reconnect, the client will generally allow applications to publish messages but because the server is offline, will be cached in the client. The library will then send those messages on reconnect. When the maximum reconnect buffer is reached, messages will no longer be publishable by the client.
+
+{{< partial "doc/reconnect_5mb.html" >}}
+
+> *As mentioned throughout this document, each client library may behave slightly differently. Please check the documentation for the library you are using.*
\ No newline at end of file
diff --git a/content/doc/writing_applications/connection_options.md b/content/doc/writing_applications/connection_options.md
new file mode 100644
index 00000000..49b01b71
--- /dev/null
+++ b/content/doc/writing_applications/connection_options.md
@@ -0,0 +1,111 @@
++++
+category = "api"
+title = "Connection Options"
+[menu.main]
+ name = "Connection Options"
+ weight = 4
+ identifier = "doc-connection-options"
+ parent = "Writing Applications"
++++
+
+The NATS client libraries offer a range of options for controlling how connections operate. Some of these are language dependent while some are library/version dependent. Please see the documentation for the client library your application uses for a full list of options. This page presents some options commonly used and options related to NATS internals that are important to understand.
+
+### Setting the Connection Name
+
+Connections can be assigned a name which will appear in some of the server monitoring data. This name is not required but can help in debugging and testing.
+
+{{< partial "doc/connect_name.html" >}}
+
+## Ping/Pong
+
+The client and server use a simple PING/PONG protocol to check that they are both still connected. The client will ping the server on a regular, configured interval so that the server usually doesn't have to initiate the PING/PONG interaction.
+
+
+
+### Set the Ping Interval
+
+If you have a connection that is going to be open a long time with few messages traveling on it, setting this PING interval can control how quickly the client will be notified of a problem. However 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:
+
+{{< partial "doc/ping_20s.html" >}}
+
+### Limit Outgoing Pings
+
+The PING/PONG interaction is also used by most of the clients as a way to flush the connection to the server. Clients that cache outgoing messages provide a flush call that will run a PING/PONG. The flush will wait for the PONG to return, telling it that all cached messages have been processed, including the PING. The number of cached PING requests can be limited in most clients to insure that traffic problems are identified early. This configuration for _max outgoing pings_ or similar will usually default to a small number and should only be increased if you are worried about fast flush traffic, perhaps in multiple threads.
+
+For example, to set the maximum number of outgoing pings to 5:
+
+{{< partial "doc/ping_5.html" >}}
+
+## Controlling the Client/Server Protocol
+
+The protocol between the client and the server is fairly simple and relies on a control line and sometimes a body. The control line contains the operations being sent, like PING or PONG, followed by a carriage return and line feed, CRLF or "\r\n". The server has a setting that can limit the maximum size of a control line. For PING and PONG this doesn't come into play, but for messages that contain subject names, the control line length can be important. The server is also configured with a maximum payload size, which limits the size of a message body. The server sends the maximum payload size to the client at connect time but doesn't currently tell the client the maximum control line size.
+
+### Set the Maximum Control Line Size
+
+Some clients will try to limit the control line size on themselves to prevent an error from the server. These clients may or may not allow you to set the size being used, but if they do, the size should be set to match the server configuration.
+
+For example, to set the maximum control line size to 2k:
+
+{{< partial "doc/control_2k.html" >}}
+
+### Get the Maximum Payload Size
+
+While the client can't control the maximum payload size, clients may provide a way for applications to get the size after the connection is made. This will allow the application to chunk or limit data as needed to pass through the server.
+
+{{< partial "doc/max_payload.html" >}}
+
+### Turning Off Echo'd Messages
+
+By default the server will echo messages. This means that if a publisher on a connection sends a message to a subject any subscribers on that same connection may receive the message. Turning off echo is a fairly new feature for the NATS server, but some of the clients already support it.
+
+
+
+Keep in mind that each connection will have to turn off echo, and that it is per connection, not per application. Also, turning echo on and off can result in a major change to your applications communications protocol since messages will flow or stop flowing based on this setting and the subscribing code won't have any indication as to why.
+
+{{< partial "doc/no_echo.html" >}}
+
+### Turn On Pedantic Mode
+
+The NATS server provides a _pedantic_ mode that does extra checks on the protocol. By default, this setting is off but you can turn it on:
+
+{{< partial "doc/connect_pedantic.html" >}}
+
+### Turn On/Off Verbose Mode
+
+The NATS server also provide a _verbose_ mode. By default, verbose mode is enabled and the server will reply to every message from the client with either a +OK or a -ERR. Most clients turn off verbose mode, which disables all of the +OK traffic. Errors are rarely subject to verbose mode and client libraries handle them as documented. To turn on verbose mode, likely for testing:
+
+{{< partial "doc/connect_verbose.html" >}}
\ No newline at end of file
diff --git a/content/doc/writing_applications/publishing.md b/content/doc/writing_applications/publishing.md
new file mode 100644
index 00000000..f496abd1
--- /dev/null
+++ b/content/doc/writing_applications/publishing.md
@@ -0,0 +1,47 @@
++++
+category = "api"
+title = "Sending Messages"
+[menu.main]
+ name = "Sending Messages"
+ weight = 6
+ identifier = "doc-sending-msg"
+ parent = "Writing Applications"
++++
+
+NATS sends and receives messages composed of a target subject, an optional reply subject and an array of bytes. Some libraries may provide helpers to convert other data formats to and from bytes, but the NATS server will treat all messages as opaque byte arrays. All of the NATS clients are designed to make sending a message simple. For example, to send the string “All is Well” to the “updates” subject as a UTF-8 string of bytes you would do:
+
+{{< partial "doc/publish_bytes.html" >}}
+
+### Reply-To
+
+The optional reply-to field when publishing a message can be used on the receiving side to respond. The reply-to subject is often called an _inbox_, and some libraries may provide a method for generating unique inbox subjects. For example to send a request to the subject `time`, with no content for the messages, you might:
+
+{{< partial "doc/publish_with_reply.html" >}}
+
+### Request-Reply
+
+The pattern of sending a message and receiving a response is encapsulated in most client libraries into a request method. Under the covers this method will publish a message with a unique reply-to subject and wait for the response before returning. In the older versions of some libraries a completely new reply-to subject is created each time. In newer versions, a subject hierarchy is used so that a single subscriber in the client library listens for a wildcard, and requests are sent with a unique child subject of a single subject.
+
+The primary difference between the request method and publishing with a reply-to is that the library is only going to accept one response, and in most libraries the request will be treated as a synchronous action. The library may provide a way to set the timeout. For example, updating the previous publish example we may request `time` with a one second timeout:
+
+{{< partial "doc/request_reply.html" >}}
+
+Ultimately you can build your own request-reply using publish-subscribe if you need a different semantic or timing.
+
+### Publishing, Caches and Flush
+
+For performance reasons, most if not all, of the client libraries will cache outgoing data. This may be as simple as a byte buffer that stores up a few messages before being pushed to the network. It is the libraries job to make sure messages flow in a high performance manner. But there may be times when an application needs to know that a message has "hit the wire." In this case, applications can use a flush call to tell the library to move data through the system.
+
+{{< partial "doc/flush.html" >}}
+
+### Flush and Ping/Pong
+
+Many of the client libraries use the PING/PONG interaction built into the NATS protocol to insure that flush pushed all of the cached messages to the server. When an application calls flush, in this case, the library will put a PING on the outgoing queue of messages, and wait for the server to send PONG before saying that the flush was successful.
+
+## Sending Structured Data
+
+Some client libraries provide helpers to send structured data while others depend on the application to perform any encoding and decoding and just take byte arrays for sending. The following example shows how to send JSON but this could easily be altered to send a protocol buffer, YAML or some other format. JSON is a text format so we also have to encode the string in most languages to bytes. We are using UTF-8, the JSON standard encoding.
+
+Take a simple _stock ticker_ that sends the symbol and price of each stock:
+
+{{< partial "doc/publish_json.html" >}}
diff --git a/content/doc/writing_applications/secure_connection.md b/content/doc/writing_applications/secure_connection.md
new file mode 100644
index 00000000..e80c58c5
--- /dev/null
+++ b/content/doc/writing_applications/secure_connection.md
@@ -0,0 +1,102 @@
++++
+category = "api"
+title = "Securing Connections"
+[menu.main]
+ name = "Securing Connections"
+ weight = 5
+ identifier = "doc-connection-security"
+ parent = "Writing Applications"
++++
+
+NATS provides several forms of security for your messages. First, you can turn on authorization which limits access to the NATS server. Second, access to specific subjects can be controlled. Third, you can use TLS to encrypt traffic between clients and the server. Finally, TLS can be used to verify client identities using certificates. By combining all of these methods you can protect access to data and data in motion.
+
+The client doesn't have control over access controls, but clients do provide the configurations required to authenticate with the server and to turn on TLS.
+
+## Server Authentication
+
+There are two kinds of authentication in NATS as well as [certificate verification](#encrypting-connections-with-tls) discussed below:
+
+* User/Password
+* Token
+
+While the server can be configured to take either of these via the configuration file, we will use the command line in these examples to make things easy. See the [server doc](/doc/managing_the_server/authentication/) for more details on the configuration file format.
+
+For the user/password examples, start the server using:
+
+```sh
+> gnatsd --user myname --pass password
+```
+
+You can encrypt passwords to pass to `gnatsd` using a simple tool provided by the server:
+
+```sh
+> go run mkpasswd.go -p
+> password: password
+> bcrypt hash: $2a$11$1oJy/wZYNTxr9jNwMNwS3eUGhBpHT3On8CL9o7ey89mpgo88VG6ba
+```
+
+and use the hashed password in the server config. The client still uses the plain text version.
+
+For the token examples, start the server using:
+
+```sh
+> gnatsd --auth mytoken
+```
+
+> The following examples use localhost:4222 so that you can start the server on your machine to try them out.
+
+### Authenticating with a User and Password
+
+When logging in with a password `gnatsd` will take either a plain text password or an encrypted password.
+
+{{< partial "doc/connect_userpass.html" >}}
+
+### Authenticating with a User and Password in the URL
+
+Most clients make it easy to pass the user name and password by accepting them in the URL for the server. This standard format is:
+
+> nats://_user_:_password_@server:port
+
+Using this format, you can connect to a server using authentication as easily as you connected with a URL:
+
+{{< partial "doc/connect_userpass_url.html" >}}
+
+### Authenticating with a Token
+
+Tokens are basically random strings, much like a password.
+
+{{< partial "doc/connect_token.html" >}}
+
+### Authenticating with a Token in the URL
+
+Some client libraries will allow you to pass the token as part of the server URL using the form:
+
+> nats://_token_@server:port
+
+Again, once you construct this URL you can connect as if this was a normal URL.
+
+{{< partial "doc/connect_token_url.html" >}}
+
+## Encrypting Connections with TLS
+
+While authentication limits which clients can connect, TLS can be used to check the server’s identity and the client’s identity and will encrypt the traffic between the two. The most secure version of TLS with NATS is to use verified client certificates. In this mode, the client can check that it trusts the certificate sent by `gnatsd` but the server will also check that it trusts the certificate sent by the client. From an applications perspective connecting to a server that does not verify client certificates may appear identical. Under the covers, disabling TLS verification removes the server side check on the client’s certificate. When started in TLS mode, `gnatsd` will require all clients to connect with TLS. Moreover, if configured to connect with TLS, client libraries will fail to connect to a server without TLS.
+
+The [Java examples repository](https://github.com/nats-io/java-nats-examples/tree/master/src/main/resources) contains certificates for starting the server in TLS mode.
+
+```sh
+> gnatsd -c /src/main/resources/tls.conf
+ or
+> gnatsd -c /src/main/resources/tls_verify.conf
+```
+
+### Connecting with TLS
+
+Connecting to a server with TLS is primarily an exercise in setting up the certificate and trust managers. For example:
+
+{{< partial "doc/connect_tls.html" >}}
+
+### Connecting with the TLS Protocol
+
+Some clients may support the `tls` protocol as well as a manual setting to turn on TLS. However, in that case there is likely some form of default or environmental settings to allow the TLS libraries to find certificate and trust stores.
+
+{{< partial "doc/connect_tls_url.html" >}}
diff --git a/content/doc/writing_applications/subjects.md b/content/doc/writing_applications/subjects.md
new file mode 100644
index 00000000..45b4d53c
--- /dev/null
+++ b/content/doc/writing_applications/subjects.md
@@ -0,0 +1,83 @@
++++
+category = "api"
+title = "Subject-based Messaging"
+[menu.main]
+ name = "Subject-based Messaging"
+ weight = 2
+ identifier = "doc-subjects"
+ parent = "Writing Applications"
++++
+
+Fundamentally NATS is about publishing and listening for messages. Both of these depend heavily on _Subjects_ which scope messages into streams or topics. At its simplest, a subject is just a string of characters that form a name the publisher and subscriber can used to find each other.
+
+
+
+ The NATS server reserves a few characters as special, and the specification says that only "alpha-numeric" characters plus the "." should be used in subject names. Subjects are case-sensitive and can not contain whitespace. For safety across clients, ASCII characters should be used, although this is subject to change in the future.
+
+### Subject Hierarchies
+
+The `.` character is used to create a subject hierarchy. For example, a world clock application might define the following to logically group related subjects:
+
+```ascii
+time.us
+time.us.east
+time.us.east.atlanta
+time.eu.east
+time.us.east.warsaw
+```
+
+to logically group related subjects.
+
+## Wildcards
+
+NATS provides two _wildcards_ that can take the place of one or more elements in a dot-separated subject. Subscribers can use these wildcards to listen to multiple subjects with a single subscription but Publishers will always use a fully specified subject, without the wildcard.
+
+### Matching A Single Token
+
+The first wildcard is `*` which will match a single token. For example, if an application wanted to listen for eastern time zones, they could subscribe to `time.*.east`, which would match `time.us.east` and `time.eu.east`.
+
+
+
+### Matching Multiple Tokens
+
+The second wildcard is `>` which will match one or more tokens, and can only appear at the end of the subject. For example, `time.us.>` will match `time.us.east` and `time.us.east.atlanta`, while `time.us.*` would only match `time.us.east` since it can't match more than one token.
+
+
diff --git a/content/doc/writing_applications/subscribing.md b/content/doc/writing_applications/subscribing.md
new file mode 100644
index 00000000..9588b492
--- /dev/null
+++ b/content/doc/writing_applications/subscribing.md
@@ -0,0 +1,124 @@
++++
+category = "api"
+title = "Receiving Messages"
+[menu.main]
+ name = "Receiving Messages"
+ weight = 7
+ identifier = "doc-receiving-msg"
+ parent = "Writing Applications"
++++
+
+Receiving messages with NATS can be very library dependent. Some languages, like Go or Java, can provide synchronous and asynchronous APIs, while others may only support one type of subscription. In all cases, the process of subscribing involves having the client library tell the NATS server that an application is interested in a particular subject. Under the covers, the client library will assign a unique id to each subscription. This id is used when the server sends messages to a specific subscription. Each subscription gets a unique id, so if the same connection is used multiple times for the same subject, the server will send multiple copies of the same message. When an application is done with a subscription it unsubscribes which tells the server to stop sending messages.
+
+### Synchronous Subscriptions
+
+Synchronous subscriptions require the application to poll for messages. This type of subscription is easy to set-up and use, but requires the application to deal with looping if multiple messages are expected. For example, to subscribe to the subject `updates` and receive a single message you could do:
+
+{{< partial "doc/subscribe_sync.html" >}}
+
+### Asynchronous Subscriptions
+
+Asynchronous subscriptions use callbacks of some form to notify an application when a message arrives. These subscriptions are usually easier to work with, but do represent some form of internal work and resource usage by the library. Check your libraries documentation for any resource usage associated with asynchronous subscriptions. The following example is the same as the previous one only with asynchronous code:
+
+{{< partial "doc/subscribe_async.html" >}}
+
+### Unsubscribing
+
+The client libraries provide a means to unsubscribe a previous subscription request. This process requires an interaction with the server, so for an asynchronous subscription there may be a small window of time where a message comes through as the unsubscribe is processed by the library. Ignoring that slight edge case, the client library will clean up any outstanding messages and tell the server that the subscription is no longer used.
+
+{{< partial "doc/unsubscribe.html" >}}
+
+### Unsubscribing After a Specified Number of Messages
+
+NATS provides a special form of unsubscribe that is configured with a message count and takes effect when that many messages are sent to a subscriber. This mechanism is very useful if only a single message is expected. There are a few important things to know about auto unsubscribe. First, the message count you provide is the total message count for a subscriber. So if you unsubscribe with a count of 1, the server will stop sending messages to that subscription after it has received one. Or if the subscriber has already received one or more messages, the unsubscribe will be immediate. This action based on history can be confusing if you try to auto unsubscribe on a long running subscription, but is logical for a new one.
+
+> Auto unsubscribe is based on the total messages sent to a subscriber, not just the new ones.
+
+Second, auto unsubscribe can also result in some tricky edge cases if a server cluster is used. The client will tell the server of the unsubscribe count when the application requests it. But if the client disconnects before the count is reached, it may have to tell another server of the remaining count. This dance between previous server notifications and new notifications on reconnect can result in unplanned behavior.
+
+Finally, most of the client libraries also track the max message count after an auto unsubscribe request. Which means that the client will stop allowing messages to flow even if the server has miscounted due to reconnects or some other failure in the client library.
+
+The following example shows unsubscribe after a single message:
+
+{{< partial "doc/unsubscribe_auto.html" >}}
+
+## Replying to a Message
+
+Incoming messages have an optional reply-to field. If that field is set, it will contain a subject to which a reply is expected. In the publishing examples we sent a request for the current time. The following code will listen for that request and respond with the time.
+
+{{< partial "doc/subscribe_w_reply.html" >}}
+
+## Wildcards
+
+There is no special code to subscribe with a wildcard subject. The main technique that may come in to play is to use the subject provided with the incoming message to determine what to do with the message.
+
+For example, you can subscribe using `*` and then act based on the actual subject.
+
+{{< partial "doc/subscribe_star.html" >}}
+
+or do something similar with `>`:
+
+{{< partial "doc/subscribe_arrow.html" >}}
+
+The following example can be used to test these two subscribers. The `*` subscriber should receive at most 2 messages, while the `>` subscriber receives 4. More importantly the `time.*.east` subscriber won't receive on `time.us.east.atlanta` because that won't match.
+
+{{< partial "doc/wildcard_tester.html" >}}
+
+## Queues
+
+Using queues, from a subscription standpoint, is super easy. The application simply includes a queue name with the subscription.
+
+
+
+For example, to subscribe to the queue `workers` with the subject `updates`:
+
+{{< partial "doc/subscribe_queue.html" >}}
+
+If you run this example with the publish examples that send to `updates`, you will see that one of the instances gets a message while the others you run won't. But the instance that receives the message will change.
+
+## Draining Connections and Subscriptions
+
+A new feature in the NATS client libraries is the ability to drain connections or subscriptions. Closing a connection, or unsubscribing from a subscription are generally considered immediate requests. Which means the library will halt messages in any pending queue or cache for subscribers. When you drain a subscription or connection, it will process any cached/pending messages before closing.
+
+For a connection the process is essentially:
+
+ 1. Drain subscriptions
+ 2. Stop new messages from being published
+ 3. Flush any remaining messages
+ 4. Close
+
+{{< partial "doc/drain_conn.html" >}}
+
+Drain provides clients that use queue subscriptions with a way to bring down applications without losing any messages. A client can bring up a new queue member, drain and shut down the old queue member, all without losing messages sent to the old client. Without drain, there is the possibility of lost messages due to queue timing.
+
+The mechanics of drain for a subscription are simpler:
+
+ 1. Unsubscribe at the server
+ 2. Process known messages
+ 3. Clean up
+
+The API for drain can generally be used instead of unsubscribe:
+
+{{< partial "doc/drain_sub.html" >}}
+
+Because draining can involve messages flowing to the server, for a flush and asynchronous message processing, the timeout for drain should generally be higher than the timeout for a simple message request/reply or similar.
+
+## Receiving Structured Data
+
+In the publishing examples, we showed how to send JSON through NATS but you can receive encoded data as well. Each client library may provide tools to help with this encoding. The core traffic to the NATS server will always be byte arrays.
+
+{{< partial "doc/subscribe_json.html" >}}
\ No newline at end of file
diff --git a/content/documentation/concepts/nats-messaging.md b/content/documentation/concepts/nats-messaging.md
deleted file mode 100644
index d06e0b37..00000000
--- a/content/documentation/concepts/nats-messaging.md
+++ /dev/null
@@ -1,28 +0,0 @@
-+++
-date = "2015-09-27"
-title = "NATS Messaging"
-category = "concepts"
-[menu.main]
- name = "Messaging"
- weight = 1
- identifier = "concepts-nats-messaging"
- parent = "Concepts"
-+++
-
-# NATS Messaging
-
-NATS messaging involves the electronic exchange of data among computer applications.
-
-NATS provides a layer between the application and the underlying physical network. Application data is encoded as a message and sent by the publisher. The message is received, decoded, and processed by one or more subscribers. A subscriber can process a NATS message [asynchronously](#async) or [synchronously](#sync).
-
-
-
-NATS makes it easy for programs to communicate across different environments, languages, and systems because all a client has to do is parse the message. NATS lets programs share common message-handling code, isolate resources and interdependencies, and scale by easily handling an increase in message volume.
-
-## Asynchronous processing
-
-Asynchronous processing uses a callback message handler to process messages. When a message arrives, the registered callback handler receives control to process the message. The client or consuming application is not blocked from performing other work while it is waiting for a message. Asynchronous processing lets you create multi-threaded dispatching designs.
-
-## Synchronous processing
-
-Synchronous processing requires that application code explicitly call a method to process an incoming message. Typically an explicit call is a blocking call that suspends processing until a message becomes available. If no message is available, the period for which the message processing call blocks is set by the client. Synchronous processing is typically used by a server whose purpose is to wait for and process incoming request messages, and to send replies to the requesting application.
diff --git a/content/documentation/concepts/nats-pub-sub.md b/content/documentation/concepts/nats-pub-sub.md
deleted file mode 100644
index ebc0d99f..00000000
--- a/content/documentation/concepts/nats-pub-sub.md
+++ /dev/null
@@ -1,26 +0,0 @@
-+++
-date = "2015-09-27"
-title = "Publish Subscribe"
-category = "concepts"
-[menu.main]
- name = "Publish Subscribe"
- weight = 2
- identifier = "concepts-nats-pub-sub"
- parent = "Concepts"
-+++
-
-# NATS Publish Subscribe
-
-NATS implements a publish subscribe message distribution model. NATS publish subscribe is a one-to-many communication. A publisher sends a message on a subject. Any active subscriber listening on that subject receives the message. Subscribers can register interest in wildcard subjects.
-
-In an asynchronous exchange, messages are delivered to the subscriber's message handler. If there is no handler, the subscription is synchronous and the client may be blocked until it can process the message.
-
-## Qualities of Service
-
-- **At Most Once Delivery (TCP reliability)** - In the basic NATS platform, if a subscriber is not listening on the subject (no subject match), or is not active when the message is sent, the message is not received. NATS is a fire-and-forget messaging system. If you need higher levels of service, you can either use [NATS Streaming](/documentation/streaming/nats-streaming-intro/), or build the additional reliability into your client(s) yourself.
-
-- **At Least Once Delivery ([NATS Streaming](/documentation/streaming/nats-streaming-intro/))** - Some applications require higher levels of service and more stringent delivery guarantees, at the potential cost of lower message throughput and higher end-to-end delivery latency. These applications rely on the underlying messaging transport to ensure that messages are delivered to subscribers irrespective of network outages or whether or not a subscriber is offline at a particular instant in time.
-
-
-
-
diff --git a/content/documentation/concepts/nats-queueing.md b/content/documentation/concepts/nats-queueing.md
deleted file mode 100644
index 75daed29..00000000
--- a/content/documentation/concepts/nats-queueing.md
+++ /dev/null
@@ -1,20 +0,0 @@
-+++
-date = "2015-09-27"
-title = "Queueing"
-category = "concepts"
-[menu.main]
- name = "Queueing"
- weight = 4
- identifier = "concepts-nats-queueing"
- parent = "Concepts"
-+++
-
-# NATS Queue Subscribers
-
-NATS provides a load balancing feature called queue subscriptions. Using queue subscribers will load balance message delivery across a group of subscribers which can be used to provide application fault tolerance and scale workload processing.
-
-To create a queue subscription, subscribers register a queue name. All subscribers with the same queue name form the queue group. As messages on the registered subject are published, one member of the group is chosen randomly to receive the message. Although queue groups have multiple subscribers, each message is consumed by only one.
-
-Queue subscribers can be asynchronous, in which case the message handler callback function processes the delivered message. Synchronous queue subscribers must build in logic to process the message. Queue subscribers are ideal for auto scaling as you can add or remove them anytime, without any configuration changes or restarting the server or clients.
-
-
diff --git a/content/documentation/concepts/nats-req-rep.md b/content/documentation/concepts/nats-req-rep.md
deleted file mode 100644
index 49e71c0c..00000000
--- a/content/documentation/concepts/nats-req-rep.md
+++ /dev/null
@@ -1,20 +0,0 @@
-+++
-date = "2015-09-27"
-title = "Request Reply"
-category = "concepts"
-[menu.main]
- name = "Request Reply"
- weight = 3
- identifier = "concepts-nats-req-rep"
- parent = "Concepts"
-+++
-
-# NATS Request Reply
-
-NATS supports two flavors of request reply messaging: point-to-point or one-to-many. Point-to-point involves the fastest or first to respond. In a one-to-many exchange, you set a limit on the number of responses the requestor may receive.
-
-In a request-response exchange, publish request operation publishes a message with a reply subject expecting a response on that reply subject. You can request to automatically wait for a response inline.
-
-The request creates an inbox and performs a request call with the inbox reply and returns the first reply received. This is optimized in the case of multiple responses.
-
-
diff --git a/content/documentation/server/gnatsd-authentication.md b/content/documentation/server/gnatsd-authentication.md
deleted file mode 100644
index 55e41ef0..00000000
--- a/content/documentation/server/gnatsd-authentication.md
+++ /dev/null
@@ -1,127 +0,0 @@
-+++
-date = "2015-09-27"
-title = "Server Authentication"
-description = ""
-category = "server"
-[menu.main]
- name = "Server Authentication"
- weight = 3
- identifier = "server-gnatsd-authentication"
- parent = "Server"
-+++
-
-# NATS Server Authentication
-
-You can enable authentication on the NATS server so that a client must authenticate its identity when connecting.
-
-The NATS server supports single user authentication via the command line or using a configuration file, and multi-user authentication via a configuration file.
-
-## Command line options for single-user authentication
-
-You can start the NATS server with single-user authentication enabled by passing in the required credentials on the command line.
-
-The following server authentication options are supported on the command line:
-
-Username and password
-
- --user user User required for connections
-
- --pass password Password required for connections
-
-Authorization token
-
- --auth token Authorization token required for connections
-
-For example:
-
-```
-gnatsd -DV --user foo --pass bar
-```
-
-Using the command line with an authorization token:
-
-```
-gnatsd -DV -auth 'S3Cr3T0k3n!'
-```
-
-## Configuration options for single-user authentication
-
-Single-user authentication configured for client connections:
-
-```
-authorization {
- user: derek
- password: T0pS3cr3t
- timeout: 1
-}
-```
-
-Single-user authentication for route connections:
-
-```
-cluster {
- authorization {
- user: route_user
- password: T0pS3cr3tT00!
- timeout: 0.5
- }
-}
-```
-
-## Multi-user authentication
-
-The NATS server configuration language supports multi-user authentication using
-
-Usage:
-
-```
-users [] // array of 2 or more users
-user // User name, constant or variable
-password // User password, constant or variable
-```
-
-You enable multi-user authentication using a NATS Server configuration file that defines the user credentials.
-
-For example:
-
-```
-authorization {
- users = [
- {user: alice, password: foo}
- {user: bob, password: bar}
- ]
-}
-```
-
-You can also use [variables](http://nats.io/documentation/server/gnatsd-config/) to set user and password values. For example, here a password is declared as a variable named PASS and assigned to Joe.
-
-```
-authorization {
- PASS: abcdefghijklmnopqrstuvwxyz0123456789
- users = [
- {user: alice, password: foo}
- {user: bob, password: bar}
- {user: joe, password: $PASS}
- ]
-}
-```
-
-## Client connection string
-
-To connect to the server as an authenticated client, you can pass in the credentials in the connection string.
-
-For example, user 'foo' with password 'bar':
-
-```
-nats://foo:bar@localhost:4222
-```
-
-Using token 'S3Cr3T0k3n!'
-
-```
-nats://S3Cr3T0k3n!@localhost:4222
-```
-
-## Tutorial
-
-See the [Writing Go Clients for NATS](/documentation/tutorials/nats-client-dev/) for an basic server authentication implementation.
diff --git a/content/documentation/server/gnatsd-container.md b/content/documentation/server/gnatsd-container.md
deleted file mode 100644
index c0b5eea2..00000000
--- a/content/documentation/server/gnatsd-container.md
+++ /dev/null
@@ -1,96 +0,0 @@
-+++
-date = "2015-09-27"
-title = "Containerization"
-description = ""
-category = "server"
-[menu.main]
- name = "Containerization"
- weight = 6
- identifier = "server-gnatsd-container"
- parent = "Server"
-+++
-
-# NATS Server Containerization
-
-The NATS server is provided as a Docker image that you can run using the Docker daemon. The NATS server Docker image is extremely lightweight, coming in at a mere 3 MB in size.
-
-Synadia actively maintains and supports the NATS server Docker image.
-
-## Docker image
-
-The NATS server Docker image is available on [Docker Hub](https://hub.docker.com/_/nats/) for public download.
-
-## Usage
-
-To use the Docker container image, install Docker and run:
-
-```
-docker pull nats
-```
-
-Run the NATS server:
-
-```
-$ docker run -d --name nats-main nats
-```
-
-By default the NATS server exposes multiple ports:
-
-- 4222 is for clients.
-- 8222 is an HTTP management port for information reporting.
-- 6222 is a routing port for clustering.
-- Use -p or -P to customize.
-
-For example:
-
-```
-$ docker run -d --name nats-main nats
-[INF] Starting gnatsd version 0.6.6
-[INF] Starting http monitor on port 8222
-[INF] Listening for route connections on 0.0.0.0:6222
-[INF] Listening for client connections on 0.0.0.0:4222
-[INF] gnatsd is ready
-```
-
-To run with the ports exposed on the host:
-
-```
-$ docker run -d -p 4222:4222 -p 6222:6222 -p 8222:8222 --name nats-main nats
-```
-
-To run a second server and cluster them together:
-
-```
-$ docker run -d --name=nats-2 --link nats-main nats --routes=nats-route://ruser:T0pS3cr3t@nats-main:6222
-```
-
-**NOTE** Since the Docker image protects routes using credentials we need to provide them above. Extracted [from Docker image configuration](https://github.com/nats-io/nats-docker/blob/master/amd64/gnatsd.conf#L16-L20)
-```
-# Routes are protected, so need to use them with --routes flag
-# e.g. --routes=nats-route://ruser:T0pS3cr3t@otherdockerhost:6222
-authorization {
- user: ruser
- password: T0pS3cr3t
- timeout: 2
-}
-```
-
-To verify the routes are connected:
-
-```
-$ docker run -d --name=nats-2 --link nats-main nats --routes=nats-route://ruser:T0pS3cr3t@nats-main:6222 -DV
-[INF] Starting gnatsd version 0.6.6
-[INF] Starting http monitor on port 8222
-[INF] Listening for route connections on :6222
-[INF] Listening for client connections on 0.0.0.0:4222
-[INF] gnatsd is ready
-[DBG] Trying to connect to route on nats-main:6222
-[DBG] 172.17.0.52:6222 - rid:1 - Route connection created
-[DBG] 172.17.0.52:6222 - rid:1 - Route connect msg sent
-[DBG] 172.17.0.52:6222 - rid:1 - Registering remote route "ee35d227433a738c729f9422a59667bb"
-[DBG] 172.17.0.52:6222 - rid:1 - Route sent local subscriptions
-```
-
-## Tutorial
-
-See the [NATS Docker tutorial](/documentation/tutorials/gnatsd-docker/) for instructions on using the NATS server Docker image.
diff --git a/content/documentation/server/gnatsd-intro.md b/content/documentation/server/gnatsd-intro.md
deleted file mode 100644
index 2a47d377..00000000
--- a/content/documentation/server/gnatsd-intro.md
+++ /dev/null
@@ -1,51 +0,0 @@
-+++
-date = "2015-09-27"
-title = "NATS Server"
-description = ""
-category = "server"
-[menu.main]
- name = "NATS Server"
- weight = 1
- identifier = "server-gnatsd-intro"
- parent = "Server"
-+++
-
-# NATS Server
-
-NATS provides a server that is written in the Go programming language. The executable name for the NATS server is `gnatsd`, which stands for Go NATS Deamon. The [NATS server](https://github.com/nats-io/gnatsd) is provided as open source software under the Apache-2.0 license. Synadia actively maintains and supports the NATS server.
-
-## Installation
-
-NATS provides a [server binary](/documentation/tutorials/gnatsd-install/) for Linux, Mac, and Windows. You can install the server from source on any platform you choose.
-
-## Usage
-
-The NATS server is easy to [use](/documentation/server/gnatsd-usage/), supports [authorization](/documentation/server/gnatsd-authorization/), and provides [logging](/documentation/server/gnatsd-logging/) facilities.
-
-## Configuration
-
-NATS provides a rich set of commands and parameters to configure all aspects of the server. You can run the server without any commands on the default port, or use the [command line](/documentation/server/gnatsd-usage/) or a [config file](/documentation/server/gnatsd-config/) to configure the server.
-
-## Containerization
-
-A fully configured NATS server is provided as a [Docker image](/documentation/server/gnatsd-container/) that you can pull from the [Docker Hub](https://hub.docker.com/_/nats/).
-
-## Clustering
-
-One of the [design goals](/documentation/#design-goals) of NATS is that it be always on and available like a dial tone. To implement this design goal, NATS provides mechanisms for [clustering servers](/documentation/server/gnatsd-cluster/) to achieve resiliency and high availability.
-
-## Auto-Pruning
-
-NATS provides built-in mechanisms to manage [slow consumers](/documentation/server/gnatsd-prune/) and [lazy listeners](/documentation/server/gnatsd-prune/). If a subscriber is not quick enough, or is not responding, the NATS server cuts it off.
-
-## Monitoring and Troubleshooting
-
-The NATS server exposes a monitoring port and several endpoints with JSON payloads that you can use to [monitor the system](/documentation/server/gnatsd-monitoring/) and create custom monitoring applications.
-
-## Server Statistics
-
-The [nats-top utility](/documentation/server/gnatsd-top/) lets you monitor NATS server activity in real time and view subscription statistics.
-
-## Performance Benchmarking and Tuning
-
-NATS provides a robust set of tooling for [performance benchmarking and tuning](/documentation/server/gnatsd-perf/) the messaging system.
diff --git a/content/documentation/server/gnatsd-perf.md b/content/documentation/server/gnatsd-perf.md
deleted file mode 100644
index d1c4cd3f..00000000
--- a/content/documentation/server/gnatsd-perf.md
+++ /dev/null
@@ -1,27 +0,0 @@
-+++
-date = "2015-09-27"
-title = "Performance Tuning"
-description = ""
-category = "server"
-[menu.main]
- name = "Performance Tuning"
- weight = 11
- identifier = "server-gnatsd-perf"
- parent = "Server"
-+++
-
-# NATS Performance Benchmarking and Tuning
-
-This section describes how to benchmark and tune NATS.
-
-## Performance benchmarking
-
-NATS provides simple scripts that let you benchmark the performance of your NATS implementation.
-
-## Performance tuning
-
-NATS makes it easy to tune the server to achieve optimal message volume and throughput for your use case.
-
-## Tutorial
-
-See the [Benchmarking tutorial](/documentation/tutorials/nats-benchmarking/) for more information.
diff --git a/content/documentation/server/gnatsd-prune.md b/content/documentation/server/gnatsd-prune.md
deleted file mode 100644
index 976995c7..00000000
--- a/content/documentation/server/gnatsd-prune.md
+++ /dev/null
@@ -1,23 +0,0 @@
-+++
-date = "2015-09-27"
-title = "Auto Pruning Clients"
-description = ""
-category = "server"
-[menu.main]
- name = "Auto Pruning Clients"
- weight = 8
- identifier = "server-gnatsd-prune"
- parent = "Server"
-+++
-
-# NATS Auto Pruning of Clients
-
-To support resiliency and high availability, NATS provides built-in mechanisms to automatically prune the registered listener interest graph that is used to keep track of subscribers, including slow consumers and lazy listeners.
-
-## Slow consumers
-
-NATS automatically handles a slow consumer. If a client is not processing messages quick enough, the NATS server cuts it off.
-
-## Lazy listeners
-
-To support scaling, NATS provides for auto-pruning of client connections. If a subscriber does not respond to ping requests from the server within the [ping-pong interval](/documentation/internals/nats-protocol/), the client is cut off (disconnected). The client will need to have reconnect logic to reconnect with the server.
diff --git a/content/documentation/server/gnatsd-usage.md b/content/documentation/server/gnatsd-usage.md
deleted file mode 100644
index 03ae0780..00000000
--- a/content/documentation/server/gnatsd-usage.md
+++ /dev/null
@@ -1,96 +0,0 @@
-+++
-date = "2015-09-27"
-title = "Server Usage"
-description = ""
-category = "server"
-[menu.main]
- name = "Server Usage"
- weight = 2
- identifier = "server-gnatsd-usage"
- parent = "Server"
-+++
-
-# NATS Server Usage
-
-Out-of-the-box you can run the NATS server without any custom settings.
-
-To configure the NATS server, you can include one or more command line arguments as described below, or you can use a [configuration file](/documentation/server/gnatsd-config).
-
-## Installation
-
-To install the NATS server:
-
-```
-go get github.com/nats-io/gnatsd
-```
-
-Refer to the [NATS installation tutorial](/documentation/tutorials/gnatsd-install/) for more detailed instructions.
-
-## Start up
-
-Run the following command to invoke the `gnatsd` binary, with no options and no configuration file, to start a server with acceptable standalone defaults (no authentication, no clustering).
-
-```
-gnatsd
-```
-
-## Server options
-
- -a, --addr HOST Bind to HOST address (default is `0.0.0.0`).
- -p, --port PORT PORT for client connections (default is `4222`).
- -P, --pid FILE File path to store PID.
- -m, --http_port PORT HTTP PORT for monitoring (use `-m 8222` to enable).
- -ms,--https_port PORT Use HTTPS PORT for monitoring
- -c, --config FILE File path to server configuration.
-
-See [Configuration](/documentation/server/gnatsd-config).
-
-## Logging options
-
- -l, --log FILE File to redirect log output
- -T, --logtime Timestamp log entries (default: true)
- -s, --syslog Enable syslog as log method.
- -r, --remote_syslog Syslog server addr (udp://localhost:514).
- -D, --debug Enable debugging output
- -V, --trace Trace the raw protocol
- -DV Debug and Trace
-
-See [Logging](/documentation/server/gnatsd-logging).
-
-## Authorization options
-
- --user user User required for connections
- --pass password Password required for connections
-
-See [Authorization](/documentation/server/gnatsd-authorization).
-
-## TLS Options
-
- --tls Enable TLS, do not verify clients (default: false)
- --tlscert FILE Server certificate file
- --tlskey FILE Private key for server certificate
- --tlsverify Enable TLS, verify client certificates
- --tlscacert FILE Client certificate CA for verification
-
-## Cluster Options
-
- --routes [rurl-1, rurl-2] Routes to solicit and connect
- --cluster [cluster url] Cluster URL for solicited routes
-
-See [Clustering](/documentation/server/gnatsd-cluster).
-
-Common Options:
-
- -h, --help Show this message
- -v, --version Show version
- --help_tls TLS help
-
-
-## API documentation
-
-For the Go server, you can use the built-in Golang documentation tool [Godoc](https://godoc.org/golang.org/x/tools/cmd/godoc) to generate API documentation. To do this:
-
-- Clone the Go server repository: `git clone git@github.com:nats-io/gnatsd.git`
-- CD to the local directory: `$GOPATH/src/github.com/nats-io/gnatsd`
-- Run the Godoc tool: `godoc -http=:6060`
-- Browse to the documentation: `http://localhost:6060/pkg/github.com/nats-io/gnatsd/server/`
diff --git a/content/documentation/tutorials/examples/async-sub.go b/content/documentation/tutorials/examples/async-sub.go
deleted file mode 100644
index c06c6882..00000000
--- a/content/documentation/tutorials/examples/async-sub.go
+++ /dev/null
@@ -1,43 +0,0 @@
-// Simple Async Subscriber
-
-package main
-
-// Import Go and NATS packages
-import (
- "log"
- "os"
- "runtime"
-
- "github.com/nats-io/go-nats"
-)
-
-func main() {
-
- // Create server connection: auth and no auth
- // natsConnection, _ := nats.Connect("nats://foo:bar@localhost:4222")
- natsConnection, err := nats.Connect(nats.DefaultURL)
-
- if err != nil {
- log.Printf("Unable to connect to DefaultURL: %v", err)
- return
- } else {
- log.Println("Connected to " + nats.DefaultURL)
- }
-
- var subject string
- if len(os.Args) > 1 {
- subject = os.Args[1]
- } else {
- subject = "foo"
- }
- // Subscribe to subject
- log.Printf("Subscribing to subject %s\n", subject)
- natsConnection.Subscribe(subject, func(msg *nats.Msg) {
-
- // Handle the message
- log.Printf("Received message '%s\n", string(msg.Data)+"'")
- })
-
- // Keep the connection alive
- runtime.Goexit()
-}
diff --git a/content/documentation/tutorials/examples/nats-rep.go b/content/documentation/tutorials/examples/nats-rep.go
deleted file mode 100644
index d5f4a596..00000000
--- a/content/documentation/tutorials/examples/nats-rep.go
+++ /dev/null
@@ -1,23 +0,0 @@
-package main
-
-import (
- "fmt"
- "github.com/nats-io/go-nats"
-)
-
-func main(){
- fmt.Println("Receiver is listening...")
-
- natsConnection, _ := nats.Connect(nats.DefaultURL)
- defer natsConnection.Close()
-
- // Receiver, responds
- donech := make(chan bool, 1)
- natsConnection.Subscribe("help.please", func(msg *nats.Msg){
- fmt.Println("Someone needs help: ", msg)
- natsConnection.Publish(msg.Reply, []byte("OK I CAN HELP!!!"))
- donech <- true
- })
-
- <-donech
-}
diff --git a/content/documentation/tutorials/examples/nats-req.go b/content/documentation/tutorials/examples/nats-req.go
deleted file mode 100644
index cac0b5d6..00000000
--- a/content/documentation/tutorials/examples/nats-req.go
+++ /dev/null
@@ -1,22 +0,0 @@
-package main
-
-import (
- "fmt"
- "time"
- "github.com/nats-io/go-nats"
-)
-
-func main(){
- fmt.Println("Sending a NATS request")
-
- natsConnection, _ := nats.Connect(nats.DefaultURL)
- defer natsConnection.Close()
-
- // Requester
- msg, err := natsConnection.Request("help.please", []byte("some message"), 1000*time.Millisecond)
- if err == nil {
- fmt.Println("Got reply: ", string(msg.Data))
- } else {
- fmt.Println("Error: ", err)
- }
-}
diff --git a/content/documentation/tutorials/examples/pub-msg.go b/content/documentation/tutorials/examples/pub-msg.go
deleted file mode 100644
index 1201eb0e..00000000
--- a/content/documentation/tutorials/examples/pub-msg.go
+++ /dev/null
@@ -1,23 +0,0 @@
-package main
-
-import (
- "fmt"
- "log"
-
- "github.com/nats-io/go-nats"
-)
-
-func main() {
- fmt.Println("Publishing Hello World")
-
- natsConnection, _ := nats.Connect(nats.DefaultURL)
- defer natsConnection.Close()
- fmt.Println("Connected to NATS server: " + nats.DefaultURL)
-
- // Msg structure
- msg := &nats.Msg{Subject: "foo", Reply: "bar", Data: []byte("Hello World")}
- natsConnection.PublishMsg(msg)
-
- log.Println("Published msg.Subject = " + msg.Subject, "| msg.Data = " + string(msg.Data))
-}
-
diff --git a/content/documentation/tutorials/examples/pub-simple.go b/content/documentation/tutorials/examples/pub-simple.go
deleted file mode 100644
index bd9fdb1f..00000000
--- a/content/documentation/tutorials/examples/pub-simple.go
+++ /dev/null
@@ -1,24 +0,0 @@
-// Simple NATS publisher
-
-package main
-
-// Import packages
-import (
- "log"
-
- "github.com/nats-io/go-nats"
-)
-
-func main() {
-
- // Connect to server no auth and auth; defer close
- natsConnection, _ := nats.Connect(nats.DefaultURL)
- // natsConnection, _ := nats.Connect("nats://foo:bar@localhost:4222")
- defer natsConnection.Close()
- log.Println("Connected to " + nats.DefaultURL)
-
- // Publish message on subject
- subject := "foo"
- natsConnection.Publish(subject, []byte("Hello NATS"))
- log.Println("Published message on subject " + subject)
-}
\ No newline at end of file
diff --git a/content/documentation/tutorials/gnatsd-install.md b/content/documentation/tutorials/gnatsd-install.md
deleted file mode 100644
index fb235bdc..00000000
--- a/content/documentation/tutorials/gnatsd-install.md
+++ /dev/null
@@ -1,105 +0,0 @@
-+++
-date = "2015-09-27"
-title = "Install NATS Server"
-description = ""
-category = "tutorials"
-[menu.main]
- name = "Install NATS Server"
- weight = 2
- identifier = "tutorial-gnatsd-install"
- parent = "Server"
-+++
-
-# Install and Run NATS Server
-
-In this tutorial you install and run the NATS server (`gnatsd`).
-You can follow this same procedure anytime you want to run the NATS server.
-
-### Install the NATS server
-
-There are numerous ways to install the NATS server.
-
-#### GitHub releases
-
-The latest official release binaries are always available on the [GitHub releases page](https://github.com/nats-io/gnatsd/releases).
-The following platforms are available:
-
- * Linux (x86, x86_64, ARM)
- * Windows (x86, x86_64)
- * macOS
-
-**The following methods may also be used. _Please note that these methods may not install the latest released version_:**
-
-#### Go
-
-Make sure [your Go environment is set up](/documentation/tutorials/go-install/)
-
-```
-go get github.com/nats-io/gnatsd
-```
-
-#### Docker Hub
-
-The latest [official Docker image](https://hub.docker.com/_/nats/) is always available on Docker Hub.
-
-
-#### Windows
-
-On Windows, the NATS server can also be installed via [Chocolatey](https://chocolatey.org/packages/gnatsd):
-
-```
-choco install gnatsd
-```
-
-#### macOS
-
-On macOS, the NATS server can alo be installed via [Homebrew](http://brewformulas.org/Gnatsd):
-
-```
-brew install gnatsd
-```
-
-### Start the NATS server
-
-You can invoke the NATS server binary, with no options and no configuration file, to start a server with acceptable standalone defaults (no authentication, no clustering).
-
-```
-gnatsd
-```
-
-When the server starts successfully, you will see that the NATS server listens for client connections on TCP Port 4222:
-
-```
-[18141] 2016/10/31 13:13:40.732616 [INF] Starting nats-server version 0.9.4
-[18141] 2016/10/31 13:13:40.732704 [INF] Listening for client connections on 0.0.0.0:4222
-[18141] 2016/10/31 13:13:40.732967 [INF] Server is ready
-```
-
-### Starting the NATS server with monitoring enabled (optional)
-
-The NATS server exposes a monitoring interface on port 8222.
-
-```
-gnatsd -m 8222
-```
-
-If you run the NATS server with monitoring enabled, you see the following messages:
-
-```
-[18159] 2016/10/31 13:14:03.055572 [INF] Starting nats-server version 0.9.4
-[18159] 2016/10/31 13:14:03.055692 [INF] Starting http monitor on 0.0.0.0:8222
-[18159] 2016/10/31 13:14:03.055762 [INF] Listening for client connections on 0.0.0.0:4222
-[18159] 2016/10/31 13:14:03.055796 [INF] Server is ready
-```
-
-### Starting the NATS server with routes enabled (optional)
-
-If routing is enabled, route (server) connections listen on port 6222.
-
-```
-[18159] 2016/10/31 13:14:03.055572 [INF] Starting nats-server version 0.9.4
-[18159] 2016/10/31 13:14:03.055692 [INF] Starting http monitor on 0.0.0.0:8222
-[18159] 2016/10/31 13:14:03.055707 [INF] Listening for route connections on 0.0.0.0:6222
-[18159] 2016/10/31 13:14:03.055762 [INF] Listening for client connections on 0.0.0.0:4222
-[18159] 2016/10/31 13:14:03.055796 [INF] Server is ready
-```
diff --git a/content/documentation/tutorials/nats-client-dev.md b/content/documentation/tutorials/nats-client-dev.md
deleted file mode 100644
index 428a6896..00000000
--- a/content/documentation/tutorials/nats-client-dev.md
+++ /dev/null
@@ -1,312 +0,0 @@
-+++
-date = "2015-09-27"
-title = "Develop Go Clients for NATS"
-description = ""
-category = "tutorials"
-[menu.main]
- name = "Develop Go Clients for NATS"
- weight = 11
- identifier = "tutorial-nats-client-dev"
- parent = "Tutorials"
-+++
-
-# Develop Go Clients for NATS
-
-This tutorial describes how to write a NATS client in Go starting with basic functionality and adding features to it.
-
-It is assumed that you have set up your Go environment and have the NATS server running.
-
-## NATS client
-
-A NATS client is a producer or consumer of a NATS message. Producers are message publishers and consumers are message subscribers. Subscribers can be asynchronous or synchronous. NATS clients communicate in a peer-to-peer fashion via the NATS server. Clients do not need to know of each other's location to communicate.
-
-There are several client libraries for NATS, and Synadia actively maintains and supports several of these. In addition, you can write your own.
-
-## Solution files
-
-The /nats-docs/tutorials/examples/ directory provides the client code that is presented in this guide. The code is explained in detail below. You are encouraged to write the code yourself and experiment, or you can run each client as-is.
-
-## Asynchronous subscriber
-
-The `async-sub.go` client is a basic asynchronous subscriber with logging included for debugging purposes.
-
-### Example code
-
-```go
-package main
-
-// Import Go and NATS packages
-import (
- "log"
- "runtime"
-
- "github.com/nats-io/go-nats"
-)
-
-func main() {
- // Create server connection
- natsConnection, _ := nats.Connect(nats.DefaultURL)
- log.Println("Connected to " + nats.DefaultURL)
-
- // Subscribe to subject
- log.Printf("Subscribing to subject 'foo'\n")
- natsConnection.Subscribe("foo", func(msg *nats.Msg) {
-
- // Handle the message
- log.Printf("Received message '%s\n", string(msg.Data)+"'")
- })
-
- // Keep the connection alive
- runtime.Goexit()
-}
-```
-
-### Import packages
-
-The client imports the required `nats` package, as well as the `runtime` Go package which is required for subscribers. We use functions from the Go `log` package to log client messages.
-
-### Create server connection
-
-The client makes a connection to the NATS server. The client connects to the NATS server running on the default port: `nats://localhost:4222`.
-
-### Subscribe to subject
-
-The client subscribes to a NATS message on subject "foo." The subscriber method returns the payload of a received message.
-
-### Handle the message
-
-The subscriber implements a message handler to process the message asynchronously. In this case, the client is simply logging each received message. Without an explicit message handler, the subscription is synchronous requiring additional client code to process the message (see synchronous subscriber example below).
-
-### Keep the connection alive
-
-The [runtime.Goexit](http://golang.org/src/runtime/panic.go?s=8250:8263#L289) function keeps the subscriber active after the main function is executed. In other words, the client does not terminate after a single message is received.
-
-### Test
-
-When you have coded the subscriber, run it as follows:
-
-```
-go run async-sub.go
-```
-
-Expected result:
-
-```
-go run async-sub.go
-2015/09/26 17:40:54 Connected to nats://localhost:4222
-2015/09/26 17:40:54 Subscribing to subject 'foo'
-```
-
-## Simple publisher
-
-The `pub-simple.go` client publishes a simple NATS message ("Hello NATS") on subject name "foo." The async-sub.go client should receive this message.
-
-### Example code
-
-```go
-package main
-
-// Import packages
-import (
- "log"
-
- "github.com/nats-io/go-nats"
-)
-
-func main() {
-
- // Connect to server; defer close
- natsConnection, _ := nats.Connect(nats.DefaultURL)
- defer natsConnection.Close()
- log.Println("Connected to " + nats.DefaultURL)
-
- // Publish message on subject
- subject := "foo"
- natsConnection.Publish(subject, []byte("Hello NATS"))
- log.Println("Published message on subject " + subject)
-}
-```
-
-### Import packages
-
-The client imports the required `nats` package, as well as the Go `log` package to log client messages.
-
-### Create server connection
-
-The client makes a connection to the NATS server. The client connects to the NATS server running on the default port: `nats://localhost:4222`. The client also defers closing the connection until after the message is sent.
-
-### Publish simple payload
-
-The client publishes the message "Hello NATS" on subject "foo." The `async-sub.go` client receives this message.
-
-After you have written this client, you can explore pub-sub messaging using the two clients you have written. Experiment with changing the subject name and use a wildcard subscriber. To go further, add a message incrementer to the client subscriber to indicate the message number received.
-
-### Test
-
-When you have coded the publisher, run it as follows:
-
-```
-go run pub-simple.go
-```
-
-Expected result:
-
-```
-go run pub-simple.go
-2015/09/26 17:48:16 Connected to nats://localhost:4222
-2015/09/26 17:48:16 Published message on subject foo
-```
-
-## Message publisher
-
-In addition to a simple message payload (string), you can also use the message struct. The solution file `pub-msg.go` demonstrates one such implementation.
-
-### Example code
-
-```go
-package main
-
-import (
- "fmt"
- "log"
-
- "github.com/nats-io/go-nats"
-)
-
-func main() {
- fmt.Println("Publishing Hello World")
-
- natsConnection, _ := nats.Connect(nats.DefaultURL)
- defer natsConnection.Close()
- fmt.Println("Connected to NATS server: " + nats.DefaultURL)
-
- // Msg structure
- msg := &nats.Msg{
- Subject: "foo",
- Reply: "bar",
- Data: []byte("Hello World"),
- }
- natsConnection.PublishMsg(msg)
-
- log.Println("Published msg.Subject = "+msg.Subject, "| msg.Data = "+string(msg.Data))
-}
-```
-
-## Synchronous subscriber
-
-A synchronous subscriber does not implement a message handler with the subscriber. Instead the client is responsible for implementing code to process the message. The client is blocked from receiving more messages until it process the received message.
-
-For example:
-
-```go
-sub, err := nc.SubscribeSync("foo")
-m, err := sub.NextMsg(timeout)
-```
-
-## Client authentication
-
-You can enable authentication on the NATS server so that a client must authenticate when connecting.
-
-As shown below, you can start the server with authentication required by passing in the required credentials with the server start command. Alternatively, you can enable authentication and set the credentials in the server configuration file.
-
-For example, using the command line:
-
-```
-gnatsd -DV -m 8222 -user foo -pass bar
-```
-
-Then, update your `async-sub.go` client as follows:
-
-```go
-package main
-
-import (
- "log"
- "runtime"
-
- "github.com/nats-io/go-nats"
-)
-
-func main() {
-
- // Create authentication server connection
- natsConnection, _ := nats.Connect("nats://foo:bar@localhost:4222")
- log.Println("Connected to " + nats.DefaultURL)
-
- // Subscribe to subject
- log.Printf("Subscribing to subject 'foo'\n")
- natsConnection.Subscribe("foo", func(msg *nats.Msg) {
-
- // Handle the message
- log.Printf("Received message '%s\n", string(msg.Data)+"'")
- })
-
- // Keep the connection alive
- runtime.Goexit()
-}
-```
-
-And, do the same for the `pub-simple.go` client as well:
-
-```go
-package main
-
-import (
- "log"
-
- "github.com/nats-io/go-nats"
-)
-
-func main() {
-
- // Connect to server with auth credentials
- natsConnectionString := "nats://foo:bar@localhost:4222"
- natsConnection, _ := nats.Connect(natsConnectionString)
- defer natsConnection.Close()
- log.Println("Connected to " + natsConnectionString)
-
- // Publish message on subject
- subject := "foo"
- natsConnection.Publish(subject, []byte("Hello NATS"))
- log.Println("Published message on subject " + subject)
-}
-```
-
-## Error handling, disconnecting and reconnecting
-
-The server reports an error similar to the following if the credentials are not right:
-
-```
-[49163] 2015/09/05 19:13:24.488825 [ERR] ::1:65218 - cid:1 - Authorization Error
-```
-
-The `-DV` flag enables trace and debug for the server, which is recommended when using auth. The server reports information such as the following:
-
-```
-$ gnatsd -DV -m 8222 -user foo -pass bar
-
-[49163] 2015/09/05 19:06:03.235424 [INF] Starting gnatsd version 0.6.6
-[49163] 2015/09/05 19:06:03.235526 [INF] Starting http monitor on port 8222
-[49163] 2015/09/05 19:06:03.236509 [INF] Listening for client connections on 0.0.0.0:4222
-[49163] 2015/09/05 19:06:03.236546 [INF] gnatsd is ready
-[49163] 2015/09/05 19:13:24.485939 [DBG] ::1:65218 - cid:1 - Client connection created
-[49163] 2015/09/05 19:13:24.488699 [TRC] ::1:65218 - cid:1 - ->> [CONNECT {"verbose":false,"pedantic":false,"ssl_required":false,"name":"","lang":"go","version":"1.1.0"}]
-[49163] 2015/09/05 19:13:24.488825 [ERR] ::1:65218 - cid:1 - Authorization Error
-[49163] 2015/09/05 19:13:24.488847 [DBG] ::1:65218 - cid:1 - Client connection closed
-[49163] 2015/09/05 19:18:56.334749 [DBG] ::1:65301 - cid:4 - Client connection created
-[49163] 2015/09/05 19:18:56.335130 [TRC] ::1:65301 - cid:4 - ->> [CONNECT {"verbose":false,"pedantic":false,"user":"foo","pass":"bar","ssl_required":false,"name":"","lang":"go","version":"1.1.0"}]
-[49163] 2015/09/05 19:18:56.335160 [TRC] ::1:65301 - cid:4 - ->> [PING]
-[49163] 2015/09/05 19:18:56.335164 [TRC] ::1:65301 - cid:4 - <<- [PONG]
-[49163] 2015/09/05 19:18:56.335452 [TRC] ::1:65301 - cid:4 - ->> [SUB foo 1]
-[49163] 2015/09/05 19:19:14.317482 [DBG] ::1:65308 - cid:5 - Client connection created
-[49163] 2015/09/05 19:19:14.317791 [TRC] ::1:65308 - cid:5 - ->> [CONNECT {"verbose":false,"pedantic":false,"user":"foo","pass":"bar","ssl_required":false,"name":"","lang":"go","version":"1.1.0"}]
-[49163] 2015/09/05 19:19:14.317816 [TRC] ::1:65308 - cid:5 - ->> [PING]
-[49163] 2015/09/05 19:19:14.317820 [TRC] ::1:65308 - cid:5 - <<- [PONG]
-[49163] 2015/09/05 19:19:14.318053 [TRC] ::1:65308 - cid:5 - ->> [PUB foo 10]
-[49163] 2015/09/05 19:19:14.318066 [TRC] ::1:65308 - cid:5 - ->> MSG_PAYLOAD: [Hello NATS]
-[49163] 2015/09/05 19:19:14.318082 [TRC] ::1:65301 - cid:4 - <<- [MSG foo 1 10]
-[49163] 2015/09/05 19:19:14.319103 [DBG] ::1:65308 - cid:5 - Client connection closed
-[49163] 2015/09/05 19:19:23.511810 [DBG] ::1:65301 - cid:4 - Client connection closed
-^C[49163] 2015/09/05 19:31:52.968571 [DBG] Trapped Signal; interrupt
-[49163] 2015/09/05 19:31:52.968585 [INF] Server Exiting..
-```
diff --git a/content/documentation/tutorials/nats-monitoring.md b/content/documentation/tutorials/nats-monitoring.md
deleted file mode 100644
index 07571ed0..00000000
--- a/content/documentation/tutorials/nats-monitoring.md
+++ /dev/null
@@ -1,51 +0,0 @@
-+++
-date = "2015-09-27"
-title = "Monitor and Debug NATS"
-description = ""
-category = "tutorials"
-[menu.main]
- name = "Monitor and Debug NATS"
- weight = 8
- identifier = "tutorial-nats-monitoring"
- parent = "Tutorials"
-+++
-
-# Monitor and Debug NATS
-
-It is easy to monitor the NATS server. When the monitoring port is enabled, the NATS server runs a lightweight web server on port 8222 with has several endpoints that return JSON objects.
-
-## Prerequisites
-
-- [Set up your Go environment](/documentation/tutorials/go-install/)
-- [Installed the NATS server](/documentation/tutorials/gnatsd-install/)
-
-## Instructions
-
-**1. In a terminal, CD to the NATS server directory.**
-
-```
-cd $GOPATH/src/github.com/nats-io/gnatsd
-```
-
-**2. Start the NATS server with monitoring enabled.**
-
-```
-gnatsd -m 8222
-```
-
-**3. Verify that the NATS server starts with the HTTP monitor on port 8222.**
-
-```
-[4528] 2015/08/19 20:09:58.572939 [INF] Starting gnatsd version 0.6.4
-[4528] 2015/08/19 20:09:58.573007 [INF] Starting http monitor on port 8222
-[4528] 2015/08/19 20:09:58.573071 [INF] Listening for client connections on 0.0.0.0:4222
-[4528] 2015/08/19 20:09:58.573090 [INF] gnatsd is ready
-```
-
-**4. Explore the monitoring endpoints.**
-
-The endpoint [http://localhost:8222/varz](http://localhost:8222/varz) reports various general statistics. If you run a subscriber and refresh the endpoint, you see that the number of connections changes from 0 to 1.
-
-The endpoint [http://localhost:8222/connz](http://localhost:8222/connz) show details about the connections. Launch a publisher and refresh the endpoint to see the statistics. The [http://localhost:8222/varz](http://localhost:8222/varz) shows the number of messages processed by the server.
-
-Launch another subscriber and check out the [http://localhost:8222/subscriptionsz](http://localhost:8222/subscriptionsz) endpoint. You’ll see that there are two subscribers. Publish more messages and monitor the results using the various endpoints. The [http://localhost:8222/routez](http://localhost:8222/routez) endpoint shows the current routes.
diff --git a/content/documentation/tutorials/nats-pub-sub.md b/content/documentation/tutorials/nats-pub-sub.md
deleted file mode 100644
index 2f1f01de..00000000
--- a/content/documentation/tutorials/nats-pub-sub.md
+++ /dev/null
@@ -1,167 +0,0 @@
-+++
-date = "2015-09-27"
-title = "Explore NATS Pub Sub"
-description = ""
-category = "tutorials"
-[menu.main]
- name = "Explore NATS Pub Sub"
- weight = 5
- identifier = "tutorial-nats-pub-sub"
- parent = "Tutorials"
-+++
-
-# Explore NATS Pub Sub
-
-NATS is a [publish subscribe messaging system](/documentation/concepts/nats-pub-sub/). Subscribers listening on a subject name receive messages on that subject. If the subscriber is not actively listening on the subject, the message is not received. Subscribers can use the wildcard subjects `*` to match a single token to match the tail of a subject.
-
-
-
-## Prerequisites
-
-- [Set up your Go environment](/documentation/tutorials/go-install/)
-- [Installed the NATS server](/documentation/tutorials/gnatsd-install/)
-
-## Instructions
-
-**1. Start the NATS server.**
-
-```
-gnatsd
-```
-
-When the server starts successfully, you will see the following messages:
-
-```
-[1] 2015/08/12 15:18:22.301550 [INF] Starting gnatsd version 0.6.4
-[1] 2015/08/12 15:18:22.301762 [INF] Listening for client connections on 0.0.0.0:4222
-[1] 2015/08/12 15:18:22.301769 [INF] gnatsd is ready
-```
-
-The NATS server listens for client connections on TCP Port 4222.
-
-**2. Start a shell or command prompt session.**
-
-You will use this session to run an example NATS client subscriber program.
-
-**3. CD to the Go client examples directory.**
-
-```
-cd $GOPATH/src/github.com/nats-io/nats/examples
-```
-
-**4. Run the client subscriber program.**
-
-```
-go run nats-sub.go
-```
-
-Where `` is a subject to listen on. A valid subject is a string that is unique in the system.
-
-For example:
-
-```
-go run nats-sub.go msg.test
-```
-
-You should see the message: *Listening on [msg.test]*
-
-**5. Start another shell or command prompt session.**
-
-You will use this session to run a NATS publisher client.
-
-**6. CD to the examples directory.**
-
-```
-cd $GOPATH/src/github.com/nats-io/nats/examples
-```
-
-**7. Publish a NATS message.**
-
-```
-go run nats-pub.go
-```
-
-Where `` is the subject name and `` is the text to publish.
-
-For example:
-
-```
-go run nats-pub.go msg.test hello
-```
-or
-
-```
-go run nats-pub.go msg.test "NATS MESSAGE"
-```
-
-**7. Verify message publication and receipt.**
-
-You should see that the publisher sends the message: *Published [msg.test] : 'NATS MESSAGE'*
-
-And that the subscriber receives the message: *[#1] Received on [msg.test]: 'NATS MESSAGE'*
-
-Note that if the receiver does not get the message, check that you are using the same subject name for the publisher and the subscriber.
-
-**8. Publish another message.**
-
-```
-go run nats-pub.go msg.test "NATS MESSAGE 2"
-```
-
-You should see that the subscriber receive message 2. Note that the message count is incremented each time your subscribing client receives a message on that subject:
-
-**9. Start another shell or command prompt session.**
-
-You will use this session to run a second NATS subscriber.
-
-**10. CD to the examples directory.**
-
-```
-cd $GOPATH/src/github.com/nats-io/nats/examples
-```
-
-**11. Subscribe to the message.**
-
-```
-go run nats-sub.go msg.test
-```
-
-**12. Publish another message using the publisher client.**
-
-```
-go run nats-pub.go msg.test "NATS MESSAGE 3"
-```
-
-Verify that both subscribing clients receive the message.
-
-**13. Start another shell or command prompt session.**
-
-You will use this session to run a third NATS subscriber.
-
-**14. CD to the examples directory.**
-
-```
-cd $GOPATH/src/github.com/nats-io/nats/examples
-```
-
-**15. Subscribe to a different message.**
-
-```
-go run nats-sub.go msg.test.new
-```
-
-All the but last subscriber receives the message. Why? Because that subscriber is not listening on the message subject used by the publisher.
-
-**16. Update the last subscriber to use a wildcard.**
-
-NATS supports the use of wildcard characters for message subscribers. (You cannot publish a message using a wildcard subject.)
-
-Change the last subscriber the listen on msg.* and run it:
-
-```
-go run nats-sub.go msg.*
-```
-
-**17. Publish another message.**
-
-This time, all three subscribing clients should receive the message.
diff --git a/content/documentation/tutorials/nats-source.md b/content/documentation/tutorials/nats-source.md
deleted file mode 100644
index 574b8e82..00000000
--- a/content/documentation/tutorials/nats-source.md
+++ /dev/null
@@ -1,84 +0,0 @@
-+++
-date = "2015-09-27"
-title = "Build NATS Server from Source"
-description = ""
-category = "tutorials"
-[menu.main]
- name = "Build NATS Server from Source"
- weight = 3
- identifier = "tutorial-nats-source"
- parent = "Tutorials"
-+++
-
-# Build NATS Server from Source
-
-The NATS server code is available as open source software under the Apache-2.0 license. You can build the source to run the NATS server on any platform supported by Go. The NATS server code requires at least version 1.4 of Go. You are encouraged to run the latest stable release of Go.
-
-## Prerequisite
-
-- [Set up your Go environment](/documentation/tutorials/go-install/)
-
-## Instructions
-
-**1. Verify your Go environment.**
-
-Run the following command to verify that you are using at least Go 1.5.
-
-```
-go version
-```
-
-**2. Create and change into $GOPATH/src/github.com/nats-io directory.**
-```
-cd $GOPATH/src
-
-mkdir -p github\.com/nats-io && cd github.com/nats-io
-```
-
-**3. Clone the NATS server repository.**
-
-```
-git clone git@github.com:nats-io/gnatsd.git
-```
-
-**4. Change to the `gnatsd` directory you cloned.**
-
-```
-cd $GOPATH/src/github.com/nats-io/gnatsd
-```
-
-**5. View the NATS server source code.**
-
-View the **main.go** file.
-
-```
-cat main.go
-```
-
-**6. Build the server from source.**
-
-Run `go build` from inside the `gnatsd` directory.
-
-```
-cd gnatsd
-
-go build
-```
-
-**7. Start nats-server.**
-
-```
-./gnatsd
-```
-
-
-
-**A successful build run produces no messages and creates an executable called `gnatsd` in this directory.**
-
-**You can invoke this binary, with no options and no configuration file for local testing. To start a server with acceptable production defaults please read our [README.md](https://github.com/nats-io/gnatsd#command-line-arguments).**
diff --git a/gulpfile.js b/gulpfile.js
index e0bbf687..fd679304 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -23,6 +23,11 @@ gulp.task('less', function() {
.pipe(gulp.dest('static/css'));
});
+gulp.task('css', function() {
+ return gulp.src('src/css/**/*.css')
+ .pipe(gulp.dest('static/css'));
+});
+
// Javascript
gulp.task('js', function() {
return gulp.src(['src/js/moment.js', 'src/js/**/*.js'])
diff --git a/layouts/doc/list.html b/layouts/doc/list.html
new file mode 100644
index 00000000..314e6505
--- /dev/null
+++ b/layouts/doc/list.html
@@ -0,0 +1,17 @@
+{{ partial "header.html" . }}
+
nc, err := nats.Connect(nats.DefaultURL)
+if err != nil {
+ log.Fatal(err)
+}
+defer nc.Close()
+
+// Do something with the connection
+
+
+
+
+
+
Connection nc = Nats.connect();
+
+// Do something with the connection
+
+nc.close();
+
+
+
+
+
let nc = NATS.connect();
+nc.on('connect', (c) => {
+ // Do something with the connection
+ doSomething();
+ // When done close it
+ nc.close();
+});
+nc.on('error', (err) => {
+ failed(err);
+});
+
+
+
+
+
nc = NATS()
+await nc.connect()
+
+# Do something with the connection
+
+await nc.close()
+
+
+
+
+
+
require 'nats/client'
+
+NATS.start do |nc|
+ # Do something with the connection
+
+ # Close the connection
+ nc.close
+end
+
+
+
+
+
// will throw an exception if connection fails
+let nc = await connect();
+// Do something with the connection
+
+// When done close it
+nc.close();
+
+
+// alternatively, you can use the Promise pattern
+let nc1: Client;
+connect()
+ .then((c) => {
+ nc1 = c;
+ // Do something with the connection
+ nc1.close();
+ });
+ // add a .catch/.finally
+
+
+
+
\ No newline at end of file
diff --git a/layouts/partials/doc/connect_multiple.html b/layouts/partials/doc/connect_multiple.html
new file mode 100644
index 00000000..69953d7a
--- /dev/null
+++ b/layouts/partials/doc/connect_multiple.html
@@ -0,0 +1,137 @@
+
+
+
Options options = new Options.Builder().
+ server("nats://localhost:1222").
+ server("nats://localhost:1223").
+ server("nats://localhost:1224").
+ build();
+Connection nc = Nats.connect(options);
+
+// Do something with the connection
+
+nc.close();
+
+
+
+
+
let nc = NATS.connect({
+ servers: [
+ "nats://demo.nats.io:4222",
+ "nats://localhost:4222"
+ ]}
+);
+
+nc.on('connect', (c) => {
+ // Do something with the connection
+ doSomething();
+ // When done close it
+ nc.close();
+});
+nc.on('error', (err) => {
+ failed(err);
+});
+
+
+
+
+
nc = NATS()
+await nc.connect(servers=[
+ "nats://127.0.0.1:1222",
+ "nats://127.0.0.1:1223",
+ "nats://127.0.0.1:1224"
+ ])
+
+# Do something with the connection
+
+await nc.close()
+
+
+
+
+
+
require 'nats/client'
+
+NATS.start(servers: ["nats://127.0.0.1:1222", "nats://127.0.0.1:1223", "nats://127.0.0.1:1224"]) do |nc|
+ # Do something with the connection
+
+ # Close the connection
+ nc.close
+end
+
+
+
+
+
// will throw an exception if connection fails
+let nc = await connect({
+ servers: [
+ "nats://demo.nats.io:4222",
+ "nats://localhost:4222"
+ ]
+});
+// Do something with the connection
+
+// When done close it
+nc.close();
+
+
+
+
\ No newline at end of file
diff --git a/layouts/partials/doc/connect_name.html b/layouts/partials/doc/connect_name.html
new file mode 100644
index 00000000..e5450dca
--- /dev/null
+++ b/layouts/partials/doc/connect_name.html
@@ -0,0 +1,117 @@
+
+
+
// Set a connection name
+nc, err := nats.Connect("demo.nats.io", nats.Name("my-connection"))
+if err != nil {
+ log.Fatal(err)
+}
+defer nc.Close()
+
+// Do something with the connection
+
+
+
+
+
+
Options options = new Options.Builder().
+ server("nats://demo.nats.io:4222").
+ connectionName("my-connection"). // Set a connection name
+ build();
+Connection nc = Nats.connect(options);
+
+// Do something with the connection
+
+nc.close();
+
nc = NATS()
+
+await nc.connect(servers=["nats://demo.nats.io:4222"], name="my-connection")
+
+# Do something with the connection.
+
+
+
+
+
+
require 'nats/client'
+
+NATS.start(servers:["nats://demo.nats.io:4222"], name: "my-connection") do |nc|
+ nc.on_reconnect do
+ puts "Got reconnected to #{nc.connected_server}"
+ end
+
+ nc.on_disconnect do |reason|
+ puts "Got disconnected! #{reason}"
+ end
+
+ nc.close
+end
+
+
+
+
+
// will throw an exception if connection fails
+let nc = await connect({
+ url: "nats://demo.nats.io:4222",
+ name: "my-connection"
+});
+
+nc.close();
+
+
+
+
\ No newline at end of file
diff --git a/layouts/partials/doc/connect_options.html b/layouts/partials/doc/connect_options.html
new file mode 100644
index 00000000..6af8e65a
--- /dev/null
+++ b/layouts/partials/doc/connect_options.html
@@ -0,0 +1,106 @@
+
+
+
nc, err := nats.Connect(nats.DefaultURL, nats.Timeout(10*time.Second))
+if err != nil {
+ log.Fatal(err)
+}
+defer nc.Close()
+
+// Do something with the connection
+
+
+
+
+
+
Options options = new Options.Builder().
+ server("nats://demo.nats.io:4222").
+ connectionTimeout(Duration.ofSeconds(10)). // Set timeout
+ build();
+Connection nc = Nats.connect(options);
+
+// Do something with the connection
+
+nc.close();
+
+
+
+
+
// connection timeout is not supported on node-nats
+
+
+
+
+
nc = NATS()
+await nc.connect(connect_timeout=2)
+
+# Do something with the connection
+
+await nc.close()
+
+
+
+
+
+
# There is currently no connect timeout as part of the Ruby NATS client API, but you can use a timer to mimic it.
+require 'nats/client'
+
+timer = EM.add_timer(5) do
+ NATS.connect do |nc|
+ # Do something with the connection
+
+ # Close the connection
+ nc.close
+ end
+end
+EM.cancel_timer(timer)
+
+
+
+
+
// connection timeout is not supported on ts-nats
+
+
+
+
\ No newline at end of file
diff --git a/layouts/partials/doc/connect_pedantic.html b/layouts/partials/doc/connect_pedantic.html
new file mode 100644
index 00000000..a7ecb548
--- /dev/null
+++ b/layouts/partials/doc/connect_pedantic.html
@@ -0,0 +1,120 @@
+
+
+
nc = NATS()
+
+await nc.connect(servers=["nats://demo.nats.io:4222"], pedantic=True)
+
+# Do something with the connection.
+
+
+
+
+
+
require 'nats/client'
+
+NATS.start(pedantic: true) do |nc|
+ nc.on_reconnect do
+ puts "Got reconnected to #{nc.connected_server}"
+ end
+
+ nc.on_disconnect do |reason|
+ puts "Got disconnected! #{reason}"
+ end
+
+ nc.close
+end
+
+
+
+
+
// will throw an exception if connection fails
+let nc = await connect({
+ url: "nats://demo.nats.io:4222",
+ pedantic: true
+});
+
+nc.close();
+
+
+
+
\ No newline at end of file
diff --git a/layouts/partials/doc/connect_status.html b/layouts/partials/doc/connect_status.html
new file mode 100644
index 00000000..b998fe93
--- /dev/null
+++ b/layouts/partials/doc/connect_status.html
@@ -0,0 +1,152 @@
+
+
+
let nc = NATS.connect("nats://demo.nats.io:4222");
+
+// on node you *must* register an error listener. If not registered
+// the library emits an 'error' event, the node process will exit.
+nc.on('error', (err) => {
+ t.log('client got an error:', err);
+});
+
+if(nc.closed) {
+ t.log('client is closed');
+} else {
+ t.log('client is not closed');
+}
+
+
+
+
+
nc = NATS()
+
+await nc.connect(
+ servers=["nats://demo.nats.io:4222"],
+ )
+
+# Do something with the connection.
+
+print("The connection is connected?", nc.is_connected)
+
+while True:
+ if nc.is_reconnecting:
+ print("Reconnecting to NATS...")
+ break
+ await asyncio.sleep(1)
+
+await nc.close()
+
+print("The connection is closed?", nc.is_closed)
+
+
+
+
+
+
NATS.start(max_reconnect_attempts: 2) do |nc|
+ puts "Connect is connected?: #{nc.connected?}"
+
+ timer = EM.add_periodic_timer(1) do
+ if nc.closing?
+ puts "Connection closed..."
+ EM.cancel_timer(timer)
+ NATS.stop
+ end
+
+ if nc.reconnecting?
+ puts "Reconnecting to NATS..."
+ next
+ end
+ end
+end
+
+
+
+
+
+
if(nc.isClosed()) {
+ t.log('the client is closed');
+} else {
+ t.log('the client is running');
+}
+
+
+
+
\ No newline at end of file
diff --git a/layouts/partials/doc/connect_tls.html b/layouts/partials/doc/connect_tls.html
new file mode 100644
index 00000000..791429de
--- /dev/null
+++ b/layouts/partials/doc/connect_tls.html
@@ -0,0 +1,221 @@
+
+
+
\ No newline at end of file
diff --git a/layouts/partials/doc/connect_tls_open.html b/layouts/partials/doc/connect_tls_open.html
new file mode 100644
index 00000000..dd1a625c
--- /dev/null
+++ b/layouts/partials/doc/connect_tls_open.html
@@ -0,0 +1,14 @@
+
+
\ No newline at end of file
diff --git a/layouts/partials/doc/connect_tls_url.html b/layouts/partials/doc/connect_tls_url.html
new file mode 100644
index 00000000..14d9bccc
--- /dev/null
+++ b/layouts/partials/doc/connect_tls_url.html
@@ -0,0 +1,196 @@
+
+
+
nc, err := nats.Connect("localhost",
+ nats.Secure(),
+ nats.RootCAs("resources/certs/ca.pem")) // May need this if server is using self-signed certificate
+if err != nil {
+ log.Fatal(err)
+}
+defer nc.Close()
+
+// Do something with the connection
+
+
+
+
+
+
class SSLUtils2 {
+ public static String KEYSTORE_PATH = "src/main/resources/keystore.jks";
+ public static String TRUSTSTORE_PATH = "src/main/resources/cacerts";
+ public static String STORE_PASSWORD = "password";
+ public static String KEY_PASSWORD = "password";
+ public static String ALGORITHM = "SunX509";
+
+ public static KeyStore loadKeystore(String path) throws Exception {
+ KeyStore store = KeyStore.getInstance("JKS");
+ BufferedInputStream in = new BufferedInputStream(new FileInputStream(path));
+
+ try {
+ store.load(in, STORE_PASSWORD.toCharArray());
+ } finally {
+ if (in != null) {
+ in.close();
+ }
+ }
+
+ return store;
+ }
+
+ public static KeyManager[] createTestKeyManagers() throws Exception {
+ KeyStore store = loadKeystore(KEYSTORE_PATH);
+ KeyManagerFactory factory = KeyManagerFactory.getInstance(ALGORITHM);
+ factory.init(store, KEY_PASSWORD.toCharArray());
+ return factory.getKeyManagers();
+ }
+
+ public static TrustManager[] createTestTrustManagers() throws Exception {
+ KeyStore store = loadKeystore(TRUSTSTORE_PATH);
+ TrustManagerFactory factory = TrustManagerFactory.getInstance(ALGORITHM);
+ factory.init(store);
+ return factory.getTrustManagers();
+ }
+
+ public static SSLContext createSSLContext() throws Exception {
+ SSLContext ctx = SSLContext.getInstance(Options.DEFAULT_SSL_PROTOCOL);
+ ctx.init(createTestKeyManagers(), createTestTrustManagers(), new SecureRandom());
+ return ctx;
+ }
+}
+
+public class ConnectTLSURL {
+ public static void main(String[] args) {
+
+ try {
+ SSLContext.setDefault(SSLUtils2.createSSLContext()); // Set the default context
+ Options options = new Options.Builder().
+ server("tls://localhost:4222"). // Use the TLS protocol
+ build();
+ Connection nc = Nats.connect(options);
+
+ // Do something with the connection
+
+ nc.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
+
EM.run do
+
+ # In order to use TLS with the Ruby NATS client, use the :tls option
+ # when customizing the connection with an empty block.
+ options = {
+ :servers => [
+ 'nats://demo.nats.io:4443',
+ ],
+ :tls => {}
+ }
+
+ NATS.connect(options) do |nc|
+ puts :connected
+ end
+end
+
+
+
+
+
// will throw an exception if connection fails
+let nc = await connect({
+ url: "tls://demo.nats.io:4443"
+});
+
+nc.close();
+
+
+
+
\ No newline at end of file
diff --git a/layouts/partials/doc/connect_token.html b/layouts/partials/doc/connect_token.html
new file mode 100644
index 00000000..93a3f548
--- /dev/null
+++ b/layouts/partials/doc/connect_token.html
@@ -0,0 +1,97 @@
+
+
+
// Set a token
+nc, err := nats.Connect("localhost", nats.Token("mytoken"))
+if err != nil {
+ log.Fatal(err)
+}
+defer nc.Close()
+
+// Do something with the connection
+
+
+
+
+
+
Options options = new Options.Builder().
+ server("nats://localhost:4222").
+ token("mytoken"). // Set a token
+ build();
+Connection nc = Nats.connect(options);
+
+// Do something with the connection
+
+nc.close();
+
+
+
+
+
let nc = NATS.connect({url: `nats://127.0.0.1:${port}`, token: "mytoken!"});
+
+
+
+
+
nc = NATS()
+
+await nc.connect(servers=["nats://mytoken@demo.nats.io:4222"])
+
+# Do something with the connection.
+
+
+
+
+
+
NATS.start(token: "deadbeef") do |nc|
+ puts "Connected using token"
+end
+
+
+
+
+
let nc = await connect({url: server.nats, token: "mytoken"});
+
+
+
+
\ No newline at end of file
diff --git a/layouts/partials/doc/connect_token_url.html b/layouts/partials/doc/connect_token_url.html
new file mode 100644
index 00000000..5eaf0ff9
--- /dev/null
+++ b/layouts/partials/doc/connect_token_url.html
@@ -0,0 +1,95 @@
+
+
+
\ No newline at end of file
diff --git a/layouts/partials/doc/connect_url.html b/layouts/partials/doc/connect_url.html
new file mode 100644
index 00000000..8cd35ace
--- /dev/null
+++ b/layouts/partials/doc/connect_url.html
@@ -0,0 +1,116 @@
+
+
+
// If connecting to the default port, the URL can be simplified
+// to just the hostname/IP.
+// That is, the connect below is equivalent to:
+// nats.Connect("nats://demo.nats.io:4222")
+nc, err := nats.Connect("demo.nats.io")
+if err != nil {
+ log.Fatal(err)
+}
+defer nc.Close()
+
+// Do something with the connection
+
+
+
+
+
+
Connection nc = Nats.connect("nats://demo.nats.io:4222");
+
+// Do something with the connection
+
+nc.close();
+
+
+
+
+
let nc = NATS.connect("nats://demo.nats.io:4222");
+nc.on('connect', (c) => {
+ // Do something with the connection
+ doSomething();
+ // When done close it
+ nc.close();
+});
+nc.on('error', (err) => {
+ failed(err);
+});
+
+
+
+
+
nc = NATS()
+await nc.connect(servers=["nats://demo.nats.io:4222"])
+
+# Do something with the connection
+
+await nc.close()
+
+
+
+
+
+
require 'nats/client'
+
+NATS.start(servers: ["nats://demo.nats.io:4222"]) do |nc|
+ # Do something with the connection
+
+ # Close the connection
+ nc.close
+end
+
+
+
+
+
// will throw an exception if connection fails
+ let nc = await connect("nats://demo.nats.io:4222");
+ // Do something with the connection
+
+ // Close the connection
+ nc.close();
+
+
+
+
\ No newline at end of file
diff --git a/layouts/partials/doc/connect_userpass.html b/layouts/partials/doc/connect_userpass.html
new file mode 100644
index 00000000..99640e78
--- /dev/null
+++ b/layouts/partials/doc/connect_userpass.html
@@ -0,0 +1,111 @@
+
+
+
// Set a user and plain text password
+nc, err := nats.Connect("localhost", nats.UserInfo("myname", "password"))
+if err != nil {
+ log.Fatal(err)
+}
+defer nc.Close()
+
+// Do something with the connection
+
+
+
+
+
+
Options options = new Options.Builder().
+ server("nats://localhost:4222").
+ userInfo("myname","password"). // Set a user and plain text password
+ build();
+Connection nc = Nats.connect(options);
+
+// Do something with the connection
+
+nc.close();
+
+
+
+
+
let nc = NATS.connect({url: server.nats, user: "myname", pass: "password"});
+
+
+
+
+
nc = NATS()
+
+await nc.connect(servers=["nats://myname:password@demo.nats.io:4222"])
+
+# Do something with the connection.
+
+
+
+
+
+
require 'nats/client'
+
+NATS.start(servers:["nats://myname:password@127.0.0.1:4222"], name: "my-connection") do |nc|
+ nc.on_error do |e|
+ puts "Error: #{e}"
+ end
+
+ nc.on_reconnect do
+ puts "Got reconnected to #{nc.connected_server}"
+ end
+
+ nc.on_disconnect do |reason|
+ puts "Got disconnected! #{reason}"
+ end
+
+ nc.close
+end
+
\ No newline at end of file
diff --git a/layouts/partials/doc/connect_userpass_url.html b/layouts/partials/doc/connect_userpass_url.html
new file mode 100644
index 00000000..0b5b3b93
--- /dev/null
+++ b/layouts/partials/doc/connect_userpass_url.html
@@ -0,0 +1,109 @@
+
+
+
// Set a user and plain text password
+nc, err := nats.Connect("myname:password@localhost")
+if err != nil {
+ log.Fatal(err)
+}
+defer nc.Close()
+
+// Do something with the connection
+
+
+
+
+
+
Connection nc = Nats.connect("nats://myname:password@localhost:4222");
+
+// Do something with the connection
+
+nc.close();
+
+
+
+
+
let url = `nats://myname:password@127.0.0.1:${port}`;
+let nc = NATS.connect(url);
+
+
+
+
+
nc = NATS()
+
+await nc.connect(servers=["nats://myname:password@demo.nats.io:4222"])
+
+# Do something with the connection.
+
+
+
+
+
+
require 'nats/client'
+
+NATS.start(servers:["nats://myname:password@127.0.0.1:4222"], name: "my-connection") do |nc|
+ nc.on_error do |e|
+ puts "Error: #{e}"
+ end
+
+ nc.on_reconnect do
+ puts "Got reconnected to #{nc.connected_server}"
+ end
+
+ nc.on_disconnect do |reason|
+ puts "Got disconnected! #{reason}"
+ end
+
+ nc.close
+end
+
\ No newline at end of file
diff --git a/layouts/partials/doc/connect_verbose.html b/layouts/partials/doc/connect_verbose.html
new file mode 100644
index 00000000..54bf20f0
--- /dev/null
+++ b/layouts/partials/doc/connect_verbose.html
@@ -0,0 +1,120 @@
+
+
+
nc = NATS()
+
+await nc.connect(servers=["nats://demo.nats.io:4222"], verbose=True)
+
+# Do something with the connection.
+
+
+
+
+
+
require 'nats/client'
+
+NATS.start(verbose: true) do |nc|
+ nc.on_reconnect do
+ puts "Got reconnected to #{nc.connected_server}"
+ end
+
+ nc.on_disconnect do |reason|
+ puts "Got disconnected! #{reason}"
+ end
+
+ nc.close
+end
+
+
+
+
+
// will throw an exception if connection fails
+let nc = await connect({
+ url: "nats://demo.nats.io:4222",
+ verbose: true
+});
+
+nc.close();
+
+
+
+
\ No newline at end of file
diff --git a/layouts/partials/doc/connection_listener.html b/layouts/partials/doc/connection_listener.html
new file mode 100644
index 00000000..11440c62
--- /dev/null
+++ b/layouts/partials/doc/connection_listener.html
@@ -0,0 +1,186 @@
+
+
+
// There is not a single listener for connection events in the NATS Go Client.
+// Instead, you can set individual event handlers using:
+
+DisconnectHandler(cb ConnHandler)
+ReconnectHandler(cb ConnHandler)
+ClosedHandler(cb ConnHandler)
+DiscoveredServersHandler(cb ConnHandler)
+ErrorHandler(cb ErrHandler)
+
+
+
+
+
class MyConnectionListener implements ConnectionListener {
+ public void connectionEvent(Connection natsConnection, Events event) {
+ System.out.println("Connection event - "+event);
+ }
+}
+
+public class SetConnectionListener {
+ public static void main(String[] args) {
+
+ try {
+ Options options = new Options.Builder().
+ server("nats://demo.nats.io:4222").
+ connectionListener(new MyConnectionListener()). // Set the listener
+ build();
+ Connection nc = Nats.connect(options);
+
+ // Do something with the connection
+
+ nc.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
+
# Asyncio NATS client can be defined a number of event callbacks
+async def disconnected_cb():
+ print("Got disconnected!")
+
+async def reconnected_cb():
+ # See who we are connected to on reconnect.
+ print("Got reconnected to {url}".format(url=nc.connected_url.netloc))
+
+async def error_cb(e):
+ print("There was an error: {}".format(e))
+
+async def closed_cb():
+ print("Connection is closed")
+
+# Setup callbacks to be notified on disconnects and reconnects
+options["disconnected_cb"] = disconnected_cb
+options["reconnected_cb"] = reconnected_cb
+
+# Setup callbacks to be notified when there is an error
+# or connection is closed.
+options["error_cb"] = error_cb
+options["closed_cb"] = closed_cb
+
+await nc.connect(**options)
+
+
+
+
+
# There is not a single listener for connection events in the Ruby NATS Client.
+# Instead, you can set individual event handlers using:
+
+NATS.on_disconnect do
+end
+
+NATS.on_reconnect do
+end
+
+NATS.on_close do
+end
+
+NATS.on_error do
+end
+
+
+
+
+
// connect will happen once - the first connect
+nc.on('connect', (nc) => {
+ // nc is the connection that connected
+ t.log('client connected');
+});
+
+nc.on('disconnect', (url) => {
+ // nc is the connection that reconnected
+ t.log('disconnected from', url);
+});
+
+nc.on('reconnecting', (url) => {
+ t.log('reconnecting to', url);
+});
+
+nc.on('reconnect', (nc, url) => {
+ // nc is the connection that reconnected
+ t.log('reconnected to', url);
+});
+
+
+
+
\ No newline at end of file
diff --git a/layouts/partials/doc/control_2k.html b/layouts/partials/doc/control_2k.html
new file mode 100644
index 00000000..62058f59
--- /dev/null
+++ b/layouts/partials/doc/control_2k.html
@@ -0,0 +1,87 @@
+
+
+
Options options = new Options.Builder().
+ server("nats://demo.nats.io:4222").
+ maxControlLine(2 * 1024). // Set the max control line to 2k
+ build();
+Connection nc = Nats.connect(options);
+
+// Do something with the connection
+
+nc.close();
+
+
+
+
+
// set this option before creating a connection
+NATS.MAX_CONTROL_LINE_SIZE = 1024*2;
+let nc = NATS.connect({
+ url: "nats://demo.nats.io:4222"
+});
+
+
+
+
+
+
# Asyncio NATS client does not allow custom control lines
+
+
+
+
+
# There is no need to customize this in the Ruby NATS client.
+
+
+
+
+
// control line size is not configurable on ts-nats
+
+
+
+
\ No newline at end of file
diff --git a/layouts/partials/doc/drain_conn.html b/layouts/partials/doc/drain_conn.html
new file mode 100644
index 00000000..48fdcc15
--- /dev/null
+++ b/layouts/partials/doc/drain_conn.html
@@ -0,0 +1,192 @@
+
+
+
wg := sync.WaitGroup{}
+wg.Add(1)
+
+errCh := make(chan error, 1)
+
+// To simulate a timeout, you would set the DrainTimeout()
+// to a value less than the time spent in the message callback,
+// so say: nats.DrainTimeout(10*time.Millisecond).
+
+nc, err := nats.Connect("demo.nats.io",
+ nats.DrainTimeout(10*time.Second),
+ nats.ErrorHandler(func(_ *nats.Conn, _ *nats.Subscription, err error) {
+ errCh <- err
+ }),
+ nats.ClosedHandler(func(_ *nats.Conn) {
+ wg.Done()
+ }))
+if err != nil {
+ log.Fatal(err)
+}
+
+// Subscribe, but add some delay while processing.
+if _, err := nc.Subscribe("foo", func(_ *nats.Msg) {
+ time.Sleep(200 * time.Millisecond)
+}); err != nil {
+ log.Fatal(err)
+}
+
+// Publish a message
+if err := nc.Publish("foo", []byte("hello")); err != nil {
+ log.Fatal(err)
+}
+
+// Drain the connection, which will close it when done.
+if err := nc.Drain(); err != nil {
+ log.Fatal(err)
+}
+
+// Wait for the connection to be closed.
+wg.Wait()
+
+// Check if there was an error
+select {
+case e := <-errCh:
+ log.Fatal(e)
+default:
+}
+
+
+
+
+
+
Connection nc = Nats.connect("nats://demo.nats.io:4222");
+
+// Use a latch to wait for a message to arrive
+CountDownLatch latch = new CountDownLatch(1);
+
+// Create a dispatcher and inline message handler
+Dispatcher d = nc.createDispatcher((msg) -> {
+ String str = new String(msg.getData(), StandardCharsets.UTF_8);
+ System.out.println(str);
+ latch.countDown();
+});
+
+// Subscribe
+d.subscribe("updates");
+
+// Wait for a message to come in
+latch.await();
+
+// Drain the connection, which will close it
+CompletableFuture<Boolean> drained = nc.drain(Duration.ofSeconds(10));
+
+// Wait for the drain to complete
+drained.get();
+
+
+
+
+
import asyncio
+from nats.aio.client import Client as NATS
+
+async def example(loop):
+ nc = NATS()
+
+ await nc.connect("nats://127.0.0.1:4222", loop=loop)
+
+ async def handler(msg):
+ print("[Received] ", msg)
+ await nc.publish(msg.reply, b'I can help')
+
+ # Can check whether client is in draining state
+ if nc.is_draining:
+ print("Connection is draining")
+
+ await nc.subscribe("help", "workers", cb=handler)
+ await nc.flush()
+
+ requests = []
+ for i in range(0, 10):
+ request = nc.request("help", b'help!', timeout=1)
+ requests.append(request)
+
+ # Wait for all the responses
+ responses = []
+ responses = await asyncio.gather(*requests)
+
+ # Gracefully close the connection.
+ await nc.drain()
+
+ print("Received {} responses".format(len(responses)))
+
+
+
+
+
NATS.start(drain_timeout: 1) do |nc|
+ NATS.subscribe('foo', queue: "workers") do |msg, reply, sub|
+ nc.publish(reply, "ACK:#{msg}")
+ end
+
+ NATS.subscribe('bar', queue: "workers") do |msg, reply, sub|
+ nc.publish(reply, "ACK:#{msg}")
+ end
+
+ NATS.subscribe('quux', queue: "workers") do |msg, reply, sub|
+ nc.publish(reply, "ACK:#{msg}")
+ end
+
+ EM.add_timer(2) do
+ next if NATS.draining?
+
+ # Drain gracefully closes the connection.
+ NATS.drain do
+ puts "Done draining. Connection is closed."
+ end
+ end
+end
+
+
+
+
+
let sub = await nc.subscribe('updates', (err, msg) => {
+ t.log('worker got message', msg.data);
+}, {queue: "workers"});
+// [end drain_sub]
+nc.flush();
+
+await nc.drain();
+// client must close when the connection drain resolves
+nc.close();
+
+
+
+
\ No newline at end of file
diff --git a/layouts/partials/doc/drain_sub.html b/layouts/partials/doc/drain_sub.html
new file mode 100644
index 00000000..47776bd3
--- /dev/null
+++ b/layouts/partials/doc/drain_sub.html
@@ -0,0 +1,174 @@
+
+
+
+ nc, err := nats.Connect("demo.nats.io")
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer nc.Close()
+
+ done := sync.WaitGroup{}
+ done.Add(1)
+
+ count := 0
+ errCh := make(chan error, 1)
+
+ msgAfterDrain := "not this one"
+
+ // This callback will process each message slowly
+ sub, err := nc.Subscribe("updates", func(m *nats.Msg) {
+ if string(m.Data) == msgAfterDrain {
+ errCh <- fmt.Errorf("Should not have received this message")
+ return
+ }
+ time.Sleep(100 * time.Millisecond)
+ count++
+ if count == 2 {
+ done.Done()
+ }
+ })
+
+ // Send 2 messages
+ for i := 0; i < 2; i++ {
+ nc.Publish("updates", []byte("hello"))
+ }
+
+ // Call Drain on the subscription. It unsubscribes but
+ // wait for all pending messages to be processed.
+ if err := sub.Drain(); err != nil {
+ log.Fatal(err)
+ }
+
+ // Send one more message, this message should not be received
+ nc.Publish("updates", []byte(msgAfterDrain))
+
+ // Wait for the subscription to have processed the 2 messages.
+ done.Wait()
+
+ // Now check that the 3rd message was not received
+ select {
+ case e := <-errCh:
+ log.Fatal(e)
+ case <-time.After(200 * time.Millisecond):
+ // OK!
+ }
+
+
+
+
+
+
Connection nc = Nats.connect("nats://demo.nats.io:4222");
+
+// Use a latch to wait for a message to arrive
+CountDownLatch latch = new CountDownLatch(1);
+
+// Create a dispatcher and inline message handler
+Dispatcher d = nc.createDispatcher((msg) -> {
+ String str = new String(msg.getData(), StandardCharsets.UTF_8);
+ System.out.println(str);
+ latch.countDown();
+});
+
+// Subscribe
+d.subscribe("updates");
+
+// Wait for a message to come in
+latch.await();
+
+// Messages that have arrived will be processed
+CompletableFuture<Boolean> drained = d.drain(Duration.ofSeconds(10));
+
+// Wait for the drain to complete
+drained.get();
+
+// Close the connection
+nc.close();
+
+
+
+
+
// Drain subscription is not supported.
+
+
+
+
+
import asyncio
+from nats.aio.client import Client as NATS
+
+async def example(loop):
+ nc = NATS()
+
+ await nc.connect("nats://127.0.0.1:4222", loop=loop)
+
+ async def handler(msg):
+ print("[Received] ", msg)
+ await nc.publish(msg.reply, b'I can help')
+
+ # Can check whether client is in draining state
+ if nc.is_draining:
+ print("Connection is draining")
+
+ sid = await nc.subscribe("help", "workers", cb=handler)
+ await nc.flush()
+
+ # Gracefully unsubscribe the subscription
+ await nc.drain(sid)
+
+
+
+
+
+
# There is currently no API to drain a single subscription, the whole connection can be drained though via NATS.drain
+
+
+
+
+
let sub = await nc.subscribe('updates', (err, msg) => {
+ t.log('worker got message', msg.data);
+}, {queue: "workers"});
+
+
+
+
\ No newline at end of file
diff --git a/layouts/partials/doc/error_listener.html b/layouts/partials/doc/error_listener.html
new file mode 100644
index 00000000..fcdb2d78
--- /dev/null
+++ b/layouts/partials/doc/error_listener.html
@@ -0,0 +1,147 @@
+
+
+
// Set the callback that will be invoked when an asynchronous error occurs.
+nc, err := nats.Connect("demo.nats.io",
+ nats.ErrorHandler(func(nc *nats.Conn, sub *nats.Subscription, err error) {
+ log.Printf("Error: %v", err)
+ }))
+if err != nil {
+ log.Fatal(err)
+}
+defer nc.Close()
+
+// Do something with the connection
+
+
+
+
+
+
class MyErrorListener implements ErrorListener {
+ public void errorOccurred(Connection conn, String error)
+ {
+ System.out.println("The server notificed the client with: "+error);
+ }
+
+ public void exceptionOccurred(Connection conn, Exception exp) {
+ System.out.println("The connection handled an exception: "+exp.getLocalizedMessage());
+ }
+
+ public void slowConsumerDetected(Connection conn, Consumer consumer) {
+ System.out.println("A slow consumer was detected.");
+ }
+}
+
+public class SetErrorListener {
+ public static void main(String[] args) {
+
+ try {
+ Options options = new Options.Builder().
+ server("nats://demo.nats.io:4222").
+ errorListener(new MyErrorListener()). // Set the listener
+ build();
+ Connection nc = Nats.connect(options);
+
+ // Do something with the connection
+
+ nc.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
+
+
+
+
+
let nc = NATS.connect("nats://demo.nats.io:4222");
+
+// on node you *must* register an error listener. If not registered
+// the library emits an 'error' event, the node process will exit.
+nc.on('error', (err) => {
+ t.log('client got an error:', err);
+});
+
require 'nats/client'
+
+NATS.start(servers:["nats://demo.nats.io:4222"]) do |nc|
+ nc.on_error do |e|
+ puts "Error: #{e}"
+ end
+
+ nc.close
+end
+
+
+
+
+
// on node you *must* register an error listener. If not registered
+// the library emits an 'error' event, the node process will exit.
+nc.on('error', (err) => {
+ t.log('client got an out of band error:', err);
+});
+
+
+
+
\ No newline at end of file
diff --git a/layouts/partials/doc/flush.html b/layouts/partials/doc/flush.html
new file mode 100644
index 00000000..0b9b0064
--- /dev/null
+++ b/layouts/partials/doc/flush.html
@@ -0,0 +1,140 @@
+
+
+
nc, err := nats.Connect("demo.nats.io")
+if err != nil {
+ log.Fatal(err)
+}
+defer nc.Close()
+
+if err := nc.Publish("updates", []byte("All is Well")); err != nil {
+ log.Fatal(err)
+}
+// Sends a PING and wait for a PONG from the server, up to the given timeout.
+// This gives guarantee that the server has processed above message.
+if err := nc.FlushTimeout(time.Second); err != nil {
+ log.Fatal(err)
+}
+
+
+
+
+
Connection nc = Nats.connect("nats://demo.nats.io:4222");
+
+nc.publish("updates", "All is Well".getBytes(StandardCharsets.UTF_8));
+nc.flush(Duration.ofSeconds(1)); // Flush the message queue
+
+nc.close();
+
+
+
+
+
let nc = NATS.connect({url: "nats://demo.nats.io:4222"});
+let start = Date.now();
+nc.flush(() => {
+ t.log('round trip completed in', Date.now() - start, 'ms');
+});
+
+nc.publish('foo');
+// function in flush is optional
+nc.flush();
+
+
+
+
+
nc = NATS()
+
+await nc.connect(servers=["nats://demo.nats.io:4222"])
+
+await nc.publish("updates", b'All is Well')
+
+# Sends a PING and wait for a PONG from the server, up to the given timeout.
+# This gives guarantee that the server has processed above message.
+await nc.flush(timeout=1)
+
+
+
+
+
+
require 'nats/client'
+require 'fiber'
+
+NATS.start(servers:["nats://127.0.0.1:4222"]) do |nc|
+ nc.subscribe("updates") do |msg|
+ puts msg
+ end
+
+ nc.publish("updates", "All is Well")
+
+ nc.flush do
+ # Sends a PING and wait for a PONG from the server, up to the given timeout.
+ # This gives guarantee that the server has processed above message at this point.
+ end
+end
+
+
+
+
+
+
let nc = await connect({
+ url: "nats://demo.nats.io:4222"
+});
+
+// you can use flush to trigger a function in your
+// application once the round-trip to the server finishes
+let start = Date.now();
+nc.flush(() => {
+ t.log('round trip completed in', Date.now() - start, 'ms');
+});
+
+nc.publish('foo');
+
+// another way, simply wait for the promise to resolve
+await nc.flush();
+
+nc.close();
+
+
+
+
\ No newline at end of file
diff --git a/layouts/partials/doc/max_payload.html b/layouts/partials/doc/max_payload.html
new file mode 100644
index 00000000..fc492685
--- /dev/null
+++ b/layouts/partials/doc/max_payload.html
@@ -0,0 +1,123 @@
+
+
+
nc, err := nats.Connect("demo.nats.io")
+if err != nil {
+ log.Fatal(err)
+}
+defer nc.Close()
+
+mp := nc.MaxPayload()
+log.Printf("Maximum payload is %v bytes", mp)
+
+// Do something with the max payload
+
+
+
+
+
+
Connection nc = Nats.connect("nats://demo.nats.io:4222");
+
+long max = nc.getMaxPayload();
+// Do something with the max payload
+
+nc.close();
+
+
+
+
+
let nc = NATS.connect("nats://demo.nats.io:4222");
+
+// on node you *must* register an error listener. If not registered
+// the library emits an 'error' event, the node process will exit.
+nc.on('error', (err) => {
+ t.log('client got an error:', err);
+});
+nc.on('connect', () => {
+ t.log(nc.info.max_payload);
+});
+
+
+
+
+
nc = NATS()
+
+await nc.connect(servers=["nats://demo.nats.io:4222"])
+
+print("Maximum payload is %d bytes" % nc.max_payload)
+
+# Do something with the max payload.
+
+
+
+
+
+
require 'nats/client'
+
+NATS.start(max_outstanding_pings: 5) do |nc|
+ nc.on_reconnect do
+ puts "Got reconnected to #{nc.connected_server}"
+ end
+
+ nc.on_disconnect do |reason|
+ puts "Got disconnected! #{reason}"
+ end
+
+ # Do something with the max_payload
+ puts "Maximum Payload is #{nc.server_info[:max_payload]} bytes"
+end
+
+
+
+
+
// connect will happen once - the first connect
+nc.on('connect', (nc: Client, url: string, options: ServerInfo) => {
+ // nc is the connection that connected
+ t.log('client connected to', url);
+ t.log('max_payload', options.max_payload);
+});
+
+
+
+
\ No newline at end of file
diff --git a/layouts/partials/doc/no_echo.html b/layouts/partials/doc/no_echo.html
new file mode 100644
index 00000000..cb43da3c
--- /dev/null
+++ b/layouts/partials/doc/no_echo.html
@@ -0,0 +1,113 @@
+
+
+
\ No newline at end of file
diff --git a/layouts/partials/doc/ping_20s.html b/layouts/partials/doc/ping_20s.html
new file mode 100644
index 00000000..ef13c4d1
--- /dev/null
+++ b/layouts/partials/doc/ping_20s.html
@@ -0,0 +1,119 @@
+
+
+
nc = NATS()
+
+await nc.connect(
+ servers=["nats://demo.nats.io:4222"],
+ # Set Ping Interval to 20 seconds
+ ping_interval=20,
+ )
+
+# Do something with the connection.
+
+
+
+
+
+
require 'nats/client'
+
+NATS.start(ping_interval: 20) do |nc|
+ nc.on_reconnect do
+ puts "Got reconnected to #{nc.connected_server}"
+ end
+
+ nc.on_disconnect do |reason|
+ puts "Got disconnected! #{reason}"
+ end
+
+ # Do something with the connection
+end
+
+
+
+
+
// will throw an exception if connection fails
+let nc = await connect({
+ pingInterval: 20*2000, //20s
+ url: "nats://demo.nats.io:4222"
+});
+nc.close();
+
+
+
+
\ No newline at end of file
diff --git a/layouts/partials/doc/ping_5.html b/layouts/partials/doc/ping_5.html
new file mode 100644
index 00000000..589d82a0
--- /dev/null
+++ b/layouts/partials/doc/ping_5.html
@@ -0,0 +1,126 @@
+
+
+
opts := nats.GetDefaultOptions()
+opts.Url = "demo.nats.io"
+// Set maximum number of PINGs out without getting a PONG back
+// before the connection will be disconnected as a stale connection.
+opts.MaxPingsOut = 5
+
+nc, err := opts.Connect()
+if err != nil {
+ log.Fatal(err)
+}
+defer nc.Close()
+
+// Do something with the connection
+
+
+
+
+
+
Options options = new Options.Builder().
+ server("nats://demo.nats.io:4222").
+ maxPingsOut(5). // Set max pings in flight
+ build();
+Connection nc = Nats.connect(options);
+
+// Do something with the connection
+
+nc.close();
+
nc = NATS()
+
+await nc.connect(
+ servers=["nats://demo.nats.io:4222"],
+ # Set maximum number of PINGs out without getting a PONG back
+ # before the connection will be disconnected as a stale connection.
+ max_outstanding_pings=5,
+ ping_interval=1,
+ )
+
+# Do something with the connection.
+
+
+
+
+
+
require 'nats/client'
+
+NATS.start(max_outstanding_pings: 5) do |nc|
+ nc.on_reconnect do
+ puts "Got reconnected to #{nc.connected_server}"
+ end
+
+ nc.on_disconnect do |reason|
+ puts "Got disconnected! #{reason}"
+ end
+
+ # Do something with the connection
+end
+
+
+
+
+
// will throw an exception if connection fails
+let nc = await connect({
+ maxPingOut: 5,
+ url: "nats://demo.nats.io:4222"
+});
+nc.close();
+
+
+
+
\ No newline at end of file
diff --git a/layouts/partials/doc/placeholder.html b/layouts/partials/doc/placeholder.html
new file mode 100644
index 00000000..dd1a625c
--- /dev/null
+++ b/layouts/partials/doc/placeholder.html
@@ -0,0 +1,14 @@
+
+
\ No newline at end of file
diff --git a/layouts/partials/doc/publish_bytes.html b/layouts/partials/doc/publish_bytes.html
new file mode 100644
index 00000000..1cb5c43d
--- /dev/null
+++ b/layouts/partials/doc/publish_bytes.html
@@ -0,0 +1,109 @@
+
+
+
nc, err := nats.Connect("demo.nats.io")
+if err != nil {
+ log.Fatal(err)
+}
+defer nc.Close()
+
+if err := nc.Publish("updates", []byte("All is Well")); err != nil {
+ log.Fatal(err)
+}
+// Make sure the message goes through before we close
+nc.Flush()
+
+
+
+
+
Connection nc = Nats.connect("nats://demo.nats.io:4222");
+
+nc.publish("updates", "All is Well".getBytes(StandardCharsets.UTF_8));
+
+// Make sure the message goes through before we close
+nc.flush(Duration.ZERO);
+nc.close();
+
+
+
+
+
let nc = NATS.connect({url: "nats://demo.nats.io:4222", preserveBuffers: true});
+let buf = Buffer.allocUnsafe(12);
+buf.fill("All is well");
+nc.publish('updates', buf);
+
\ No newline at end of file
diff --git a/layouts/partials/doc/publish_json.html b/layouts/partials/doc/publish_json.html
new file mode 100644
index 00000000..243f2737
--- /dev/null
+++ b/layouts/partials/doc/publish_json.html
@@ -0,0 +1,142 @@
+
+
+
\ No newline at end of file
diff --git a/layouts/partials/doc/publish_with_reply.html b/layouts/partials/doc/publish_with_reply.html
new file mode 100644
index 00000000..dc4e963d
--- /dev/null
+++ b/layouts/partials/doc/publish_with_reply.html
@@ -0,0 +1,194 @@
+
+
+
nc, err := nats.Connect("demo.nats.io")
+if err != nil {
+ log.Fatal(err)
+}
+defer nc.Close()
+
+// Create a unique subject name
+uniqueReplyTo := nats.NewInbox()
+
+// Listen for a single response
+sub, err := nc.SubscribeSync(uniqueReplyTo)
+if err != nil {
+ log.Fatal(err)
+}
+
+// Send the request
+if err := nc.PublishRequest("time", uniqueReplyTo, nil); err != nil {
+ log.Fatal(err)
+}
+
+// Read the reply
+msg, err := sub.NextMsg(time.Second)
+if err != nil {
+ log.Fatal(err)
+}
+
+// Use the response
+log.Printf("Reply: %s", msg.Data)
+
+// Close the connection
+nc.Close()
+
+
+
+
+
Connection nc = Nats.connect("nats://demo.nats.io:4222");
+
+// Create a unique subject name
+String uniqueReplyTo = NUID.nextGlobal();
+
+// Listen for a single response
+Subscription sub = nc.subscribe(uniqueReplyTo);
+sub.unsubscribe(1);
+
+// Send the request
+nc.publish("time", uniqueReplyTo, null);
+
+// Read the reply
+Message msg = sub.nextMessage(Duration.ofSeconds(1));
+
+// Use the response
+System.out.println(new String(msg.getData(), StandardCharsets.UTF_8));
+
+// Close the connection
+nc.close();
+
+
+
+
+
// set up a subscription to process the request
+nc.subscribe('time', (msg, reply) => {
+ if(reply) {
+ nc.publish(reply, new Date().toLocaleTimeString());
+ }
+});
+
+// create a subscription subject that the responding send replies to
+let inbox = NATS.createInbox();
+nc.subscribe(inbox, {max: 1}, (msg) => {
+ t.log('the time is', msg);
+ nc.close();
+});
+
+nc.publish('time', "", inbox);
+
require 'nats/client'
+require 'fiber'
+
+NATS.start(servers:["nats://127.0.0.1:4222"]) do |nc|
+ Fiber.new do
+ f = Fiber.current
+
+ nc.subscribe("time") do |msg, reply|
+ f.resume msg
+ end
+
+ nc.publish("time", 'example', NATS.create_inbox)
+
+ # Use the response
+ msg = Fiber.yield
+ puts "Reply: #{msg}"
+
+ end.resume
+end
+
+
+
+
+
+
// set up a subscription to process the request
+await nc.subscribe('time', (err, msg) => {
+ if (err) {
+ // this example is running inside of a promise
+ reject();
+ return;
+ }
+ if (msg.reply) {
+ nc.publish(msg.reply, new Date().toLocaleTimeString());
+ }
+});
+
+// create a subscription subject that the responding send replies to
+let inbox = createInbox();
+await nc.subscribe(inbox, (err, msg) => {
+ t.log('the time is', msg.data);
+ // this example is running inside of a promise
+ nc.close();
+ resolve();
+}, {max: 1});
+
+nc.publish('time', "", inbox);
+
+
+
+
\ No newline at end of file
diff --git a/layouts/partials/doc/reconnect_10s.html b/layouts/partials/doc/reconnect_10s.html
new file mode 100644
index 00000000..dbf704d6
--- /dev/null
+++ b/layouts/partials/doc/reconnect_10s.html
@@ -0,0 +1,114 @@
+
+
+
nc = NATS()
+await nc.connect(
+ servers=["nats://demo.nats.io:4222"],
+ reconnect_time_wait=10,
+ )
+
+# Do something with the connection
+
+await nc.close()
+
+
+
+
+
+
require 'nats/client'
+
+NATS.start(servers: ["nats://127.0.0.1:1222", "nats://127.0.0.1:1223", "nats://127.0.0.1:1224"], reconnect_time_wait: 10) do |nc|
+ # Do something with the connection
+
+ # Close the connection
+ nc.close
+end
+
+
+
+
+
// will throw an exception if connection fails
+let nc = await connect({
+ reconnectTimeWait: 10*1000, //10s
+ servers: ["nats://demo.nats.io:4222"]
+});
+nc.close();
+
+
+
+
\ No newline at end of file
diff --git a/layouts/partials/doc/reconnect_10x.html b/layouts/partials/doc/reconnect_10x.html
new file mode 100644
index 00000000..9e436d5a
--- /dev/null
+++ b/layouts/partials/doc/reconnect_10x.html
@@ -0,0 +1,114 @@
+
+
+
// Set max reconnects attempts
+nc, err := nats.Connect("demo.nats.io", nats.MaxReconnects(10))
+if err != nil {
+ log.Fatal(err)
+}
+defer nc.Close()
+
+// Do something with the connection
+
+
+
+
+
+
Options options = new Options.Builder().
+ server("nats://demo.nats.io:4222").
+ maxReconnects(10). // Set max reconnect attempts
+ build();
+Connection nc = Nats.connect(options);
+
+// Do something with the connection
+
+nc.close();
+
nc = NATS()
+await nc.connect(
+ servers=["nats://demo.nats.io:4222"],
+ max_reconnect_attempts=10,
+ )
+
+# Do something with the connection
+
+await nc.close()
+
+
+
+
+
+
require 'nats/client'
+
+NATS.start(servers: ["nats://127.0.0.1:1222", "nats://127.0.0.1:1223", "nats://127.0.0.1:1224"], max_reconnect_attempts: 10) do |nc|
+ # Do something with the connection
+
+ # Close the connection
+ nc.close
+end
+
+
+
+
+
// will throw an exception if connection fails
+let nc = await connect({
+ maxReconnectAttempts: 10,
+ servers: ["nats://demo.nats.io:4222"]
+});
+nc.close();
+
+
+
+
\ No newline at end of file
diff --git a/layouts/partials/doc/reconnect_5mb.html b/layouts/partials/doc/reconnect_5mb.html
new file mode 100644
index 00000000..6aeb8663
--- /dev/null
+++ b/layouts/partials/doc/reconnect_5mb.html
@@ -0,0 +1,90 @@
+
+
+
// Set reconnect buffer size in bytes (5 MB)
+nc, err := nats.Connect("demo.nats.io", nats.ReconnectBufSize(5*1024*1024))
+if err != nil {
+ log.Fatal(err)
+}
+defer nc.Close()
+
+// Do something with the connection
+
+
+
+
+
+
Options options = new Options.Builder().
+ server("nats://demo.nats.io:4222").
+ reconnectBufferSize(5 * 1024 * 1024). // Set buffer in bytes
+ build();
+Connection nc = Nats.connect(options);
+
+// Do something with the connection
+
+nc.close();
+
+
+
+
+
// Reconnect buffer size is not configurable on node-nats
+
+
+
+
+
# Asyncio NATS client currentply does not implement a reconnect buffer
+
+
+
+
+
# There is currently no reconnect pending buffer as part of the Ruby NATS client.
+
+
+
+
+
// Reconnect buffer size is not configurable on ts-nats
+
+
+
+
\ No newline at end of file
diff --git a/layouts/partials/doc/reconnect_event.html b/layouts/partials/doc/reconnect_event.html
new file mode 100644
index 00000000..fb62c2d2
--- /dev/null
+++ b/layouts/partials/doc/reconnect_event.html
@@ -0,0 +1,150 @@
+
+
+
// Connection event handlers are invoked asynchronously
+// and the state of the connection may have changed when
+// the callback is invoked.
+nc, err := nats.Connect("demo.nats.io",
+ nats.DisconnectHandler(func(nc *nats.Conn) {
+ // handle disconnect event
+ }),
+ nats.ReconnectHandler(func(nc *nats.Conn) {
+ // handle reconnect event
+ }))
+if err != nil {
+ log.Fatal(err)
+}
+defer nc.Close()
+
+// Do something with the connection
+
+
+
+
+
+
Options options = new Options.Builder().
+ server("nats://demo.nats.io:4222").
+ connectionListener((conn, type) -> {
+ if (type == Events.RECONNECTED) {
+ // handle reconnected
+ } else if (type == Events.DISCONNECTED) {
+ // handle disconnected, wait for reconnect
+ }
+ }).
+ build();
+Connection nc = Nats.connect(options);
+
+// Do something with the connection
+
+nc.close();
+
nc = NATS()
+
+async def disconnected_cb():
+ print("Got disconnected!")
+
+async def reconnected_cb():
+ # See who we are connected to on reconnect.
+ print("Got reconnected to {url}".format(url=nc.connected_url.netloc))
+
+await nc.connect(
+ servers=["nats://demo.nats.io:4222"],
+ reconnect_time_wait=10,
+ reconnected_cb=reconnected_cb,
+ disconnected_cb=disconnected_cb,
+ )
+
+# Do something with the connection.
+
+
+
+
+
+
require 'nats/client'
+
+NATS.start(servers: ["nats://127.0.0.1:1222", "nats://127.0.0.1:1223", "nats://127.0.0.1:1224"]) do |nc|
+ # Do something with the connection
+ nc.on_reconnect do
+ puts "Got reconnected to #{nc.connected_server}"
+ end
+
+ nc.on_disconnect do |reason|
+ puts "Got disconnected! #{reason}"
+ end
+end
+
+
+
+
+
// will throw an exception if connection fails
+let nc = await connect({
+ maxReconnectAttempts: 10,
+ servers: ["nats://demo.nats.io:4222"]
+});
+// first argument is the connection (same as nc in this case)
+// second argument is the url of the server where the client
+// connected
+nc.on('reconnect', (conn, server) => {
+ console.log('reconnected to', server);
+});
+nc.close();
+
+
+
+
\ No newline at end of file
diff --git a/layouts/partials/doc/reconnect_no_random.html b/layouts/partials/doc/reconnect_no_random.html
new file mode 100644
index 00000000..05857569
--- /dev/null
+++ b/layouts/partials/doc/reconnect_no_random.html
@@ -0,0 +1,126 @@
+
+
+
require 'nats/client'
+
+NATS.start(servers: ["nats://127.0.0.1:1222", "nats://127.0.0.1:1223", "nats://127.0.0.1:1224"], dont_randomize_servers: true) do |nc|
+ # Do something with the connection
+
+ # Close the connection
+ nc.close
+end
+
+
+
+
+
// will throw an exception if connection fails
+let nc = await connect({
+ noRandomize: false,
+ servers: ["nats://127.0.0.1:4443",
+ "nats://demo.nats.io:4222"
+ ]
+});
+nc.close();
+
+
+
+
\ No newline at end of file
diff --git a/layouts/partials/doc/reconnect_none.html b/layouts/partials/doc/reconnect_none.html
new file mode 100644
index 00000000..92947404
--- /dev/null
+++ b/layouts/partials/doc/reconnect_none.html
@@ -0,0 +1,118 @@
+
+
+
require 'nats/client'
+
+NATS.start(servers: ["nats://127.0.0.1:1222", "nats://127.0.0.1:1223", "nats://127.0.0.1:1224"], reconnect: false) do |nc|
+ # Do something with the connection
+
+ # Close the connection
+ nc.close
+end
+
+
+
+
+
// will throw an exception if connection fails
+let nc = await connect({
+ reconnect: false,
+ servers: ["nats://demo.nats.io:4222"]
+});
+nc.close();
+
+
+
+
\ No newline at end of file
diff --git a/layouts/partials/doc/request_reply.html b/layouts/partials/doc/request_reply.html
new file mode 100644
index 00000000..fa3a5689
--- /dev/null
+++ b/layouts/partials/doc/request_reply.html
@@ -0,0 +1,133 @@
+
+
+
nc = NATS()
+
+async def sub(msg):
+ await nc.publish(msg.reply, b'response')
+
+await nc.connect(servers=["nats://demo.nats.io:4222"])
+await nc.subscribe("time", cb=sub)
+
+# Send the request
+try:
+ msg = await nc.request("time", b'', timeout=1)
+ # Use the response
+ print("Reply:", msg)
+except asyncio.TimeoutError:
+ print("Timed out waiting for response")
+
+
+
+
+
+
require 'nats/client'
+require 'fiber'
+
+NATS.start(servers:["nats://127.0.0.1:4222"]) do |nc|
+ nc.subscribe("time") do |msg, reply|
+ nc.publish(reply, "response")
+ end
+
+ Fiber.new do
+ # Use the response
+ msg = nc.request("time", "")
+ puts "Reply: #{msg}"
+ end.resume
+end
+
+
+
+
+
+
let msg = await nc.request('time', 1000);
+t.log('the time is', msg.data);
+nc.close();
+
+
+
+
\ No newline at end of file
diff --git a/layouts/partials/doc/servers_added.html b/layouts/partials/doc/servers_added.html
new file mode 100644
index 00000000..a41099ee
--- /dev/null
+++ b/layouts/partials/doc/servers_added.html
@@ -0,0 +1,119 @@
+
+
+
// Be notified if a new server joins the cluster.
+// Print all the known servers and the only the ones that were discovered.
+nc, err := nats.Connect("demo.nats.io",
+ nats.DiscoveredServersHandler(func(nc *nats.Conn) {
+ log.Printf("Known servers: %v\n", nc.Servers())
+ log.Printf("Discovered servers: %v\n", nc.DiscoveredServers())
+ }))
+if err != nil {
+ log.Fatal(err)
+}
+defer nc.Close()
+
+// Do something with the connection
+
+
+
+
+
+
class ServersAddedListener implements ConnectionListener {
+ public void connectionEvent(Connection nc, Events event) {
+ if (event == Events.DISCOVERED_SERVERS) {
+ for (String server : nc.getServers()) {
+ System.out.println("Known server: "+server);
+ }
+ }
+ }
+}
+
+public class ListenForNewServers {
+ public static void main(String[] args) {
+
+ try {
+ Options options = new Options.Builder().
+ server("nats://demo.nats.io:4222").
+ connectionListener(new ServersAddedListener()). // Set the listener
+ build();
+ Connection nc = Nats.connect(options);
+
+ // Do something with the connection
+
+ nc.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
+
\ No newline at end of file
diff --git a/layouts/partials/doc/side-menu.html b/layouts/partials/doc/side-menu.html
new file mode 100644
index 00000000..e5cb0bb5
--- /dev/null
+++ b/layouts/partials/doc/side-menu.html
@@ -0,0 +1,28 @@
+
+ {{ $currentNode := . }}
+
+ {{ range .Site.Menus.main }}
+ {{ if eq .Identifier "doc" }}
+ {{ if .HasChildren }}
+
\ No newline at end of file
diff --git a/layouts/partials/doc/slow_listener.html b/layouts/partials/doc/slow_listener.html
new file mode 100644
index 00000000..90e6da8f
--- /dev/null
+++ b/layouts/partials/doc/slow_listener.html
@@ -0,0 +1,162 @@
+
+
+
// Set the callback that will be invoked when an asynchronous error occurs.
+nc, err := nats.Connect("demo.nats.io",
+ nats.ErrorHandler(func(nc *nats.Conn, sub *nats.Subscription, err error) {
+ if err == nats.ErrSlowConsumer {
+ dropped, _ := sub.Dropped()
+ log.Printf("Slow consumer on subject %s dropped %d messages\n",
+ sub.Subject, dropped)
+ }
+ }))
+if err != nil {
+ log.Fatal(err)
+}
+defer nc.Close()
+
+// Do something with the connection
+
+
+
+
+
+
class SlowConsumerReporter implements ErrorListener {
+ public void errorOccurred(Connection conn, String error)
+ {
+ }
+
+ public void exceptionOccurred(Connection conn, Exception exp) {
+ }
+
+ // Detect slow consumers
+ public void slowConsumerDetected(Connection conn, Consumer consumer) {
+ // Get the dropped count
+ System.out.println("A slow consumer dropped messages: "+ consumer.getDroppedCount());
+ }
+}
+
+public class SlowConsumerListener {
+ public static void main(String[] args) {
+
+ try {
+ Options options = new Options.Builder().
+ server("nats://demo.nats.io:4222").
+ errorListener(new SlowConsumerReporter()). // Set the listener
+ build();
+ Connection nc = Nats.connect(options);
+
+ // Do something with the connection
+
+ nc.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
+
+
+
+
+
// slow consumer detection is not configurable on node-nats
+
+
+
+
+
+ nc = NATS()
+
+ async def error_cb(e):
+ if type(e) is nats.aio.errors.ErrSlowConsumer:
+ print("Slow consumer error, unsubscribing from handling further messages...")
+ await nc.unsubscribe(e.sid)
+
+ await nc.connect(
+ servers=["nats://demo.nats.io:4222"],
+ error_cb=error_cb,
+ )
+
+ msgs = []
+ future = asyncio.Future()
+ async def cb(msg):
+ nonlocal msgs
+ nonlocal future
+ print(msg)
+ msgs.append(msg)
+
+ if len(msgs) == 3:
+ # Head of line blocking on other messages caused
+ # by single message proccesing taking long...
+ await asyncio.sleep(1)
+
+ await nc.subscribe("updates", cb=cb, pending_msgs_limit=5)
+
+ for i in range(0, 10):
+ await nc.publish("updates", "msg #{}".format(i).encode())
+ await asyncio.sleep(0)
+
+ try:
+ await asyncio.wait_for(future, 1)
+ except asyncio.TimeoutError:
+ pass
+
+ for msg in msgs:
+ print("[Received]", msg)
+
+ await nc.close()
+
+
+
+
+
+
# The Ruby NATS client currently does not have option to customize slow consumer limits per sub.
+
+
+
+
+
// slow consumer detection is not configurable on ts-nats
+
+
+
+
\ No newline at end of file
diff --git a/layouts/partials/doc/slow_pending_limits.html b/layouts/partials/doc/slow_pending_limits.html
new file mode 100644
index 00000000..a06a5320
--- /dev/null
+++ b/layouts/partials/doc/slow_pending_limits.html
@@ -0,0 +1,129 @@
+
+
+
# The Ruby NATS client currently does not have option to customize slow consumer limits per sub.
+
+
+
+
+
// slow pending limits are not configurable on ts-nats
+
+
+
+
\ No newline at end of file
diff --git a/layouts/partials/doc/subscribe_arrow.html b/layouts/partials/doc/subscribe_arrow.html
new file mode 100644
index 00000000..f8a9269e
--- /dev/null
+++ b/layouts/partials/doc/subscribe_arrow.html
@@ -0,0 +1,203 @@
+
+
+
nc, err := nats.Connect("demo.nats.io")
+if err != nil {
+ log.Fatal(err)
+}
+defer nc.Close()
+
+// Use a WaitGroup to wait for 4 messages to arrive
+wg := sync.WaitGroup{}
+wg.Add(4)
+
+// Subscribe
+if _, err := nc.Subscribe("time.>", func(m *nats.Msg) {
+ log.Printf("%s: %s", m.Subject, m.Data)
+ wg.Done()
+}); err != nil {
+ log.Fatal(err)
+}
+
+// Wait for the 4 messages to come in
+wg.Wait()
+
+// Close the connection
+nc.Close()
+
+
+
+
+
Connection nc = Nats.connect("nats://demo.nats.io:4222");
+
+// Use a latch to wait for 4 messages to arrive
+CountDownLatch latch = new CountDownLatch(4);
+
+// Create a dispatcher and inline message handler
+Dispatcher d = nc.createDispatcher((msg) -> {
+ String subject = msg.getSubject();
+ String str = new String(msg.getData(), StandardCharsets.UTF_8);
+ System.out.println(subject + ": " + str);
+ latch.countDown();
+});
+
+// Subscribe
+d.subscribe("time.>");
+
+// Wait for messages to come in
+latch.await();
+
+// Close the connection
+nc.close();
+
+
+
+
+
nc.subscribe('time.>', (msg, reply, subject) => {
+ // converting timezones correctly in node requires a library
+ // this doesn't take into account *many* things.
+ let time = "";
+ switch (subject) {
+ case 'time.us.east':
+ time = new Date().toLocaleTimeString("en-us", {timeZone: "America/New_York"});
+ break;
+ case 'time.us.central':
+ time = new Date().toLocaleTimeString("en-us", {timeZone: "America/Chicago"});
+ break;
+ case 'time.us.mountain':
+ time = new Date().toLocaleTimeString("en-us", {timeZone: "America/Denver"});
+ break;
+ case 'time.us.west':
+ time = new Date().toLocaleTimeString("en-us", {timeZone: "America/Los_Angeles"});
+ break;
+ default:
+ time = "I don't know what you are talking about Willis";
+ }
+ t.log(subject, time);
+});
+
+
+
+
+
nc = NATS()
+
+await nc.connect(servers=["nats://demo.nats.io:4222"])
+
+# Use queue to wait for 4 messages to arrive
+queue = asyncio.Queue()
+async def cb(msg):
+ await queue.put(msg)
+
+await nc.subscribe("time.>", cb=cb)
+
+# Send 2 messages and wait for them to come in
+await nc.publish("time.A.east", b'A')
+await nc.publish("time.B.east", b'B')
+await nc.publish("time.C.west", b'C')
+await nc.publish("time.D.west", b'D')
+
+for i in range(0, 4):
+ msg = await queue.get()
+ print("Msg:", msg)
+
+await nc.close()
+
+
+
+
+
+
require 'nats/client'
+require 'fiber'
+
+NATS.start(servers:["nats://127.0.0.1:4222"]) do |nc|
+ Fiber.new do
+ f = Fiber.current
+
+ nc.subscribe("time.>") do |msg, reply|
+ f.resume Time.now.to_f
+ end
+
+ nc.publish("time.A.east", "A")
+ nc.publish("time.B.east", "B")
+ nc.publish("time.C.west", "C")
+ nc.publish("time.D.west", "D")
+
+ # Use the response
+ 4.times do
+ msg = Fiber.yield
+ puts "Msg: #{msg}"
+ end
+ end.resume
+end
+
+
+
+
+
+
await nc.subscribe('time.>', (err, msg) => {
+ // converting timezones correctly in node requires a library
+ // this doesn't take into account *many* things.
+ let time = "";
+ switch (msg.subject) {
+ case 'time.us.east':
+ time = new Date().toLocaleTimeString("en-us", {timeZone: "America/New_York"});
+ break;
+ case 'time.us.central':
+ time = new Date().toLocaleTimeString("en-us", {timeZone: "America/Chicago"});
+ break;
+ case 'time.us.mountain':
+ time = new Date().toLocaleTimeString("en-us", {timeZone: "America/Denver"});
+ break;
+ case 'time.us.west':
+ time = new Date().toLocaleTimeString("en-us", {timeZone: "America/Los_Angeles"});
+ break;
+ default:
+ time = "I don't know what you are talking about Willis";
+ }
+ t.log(msg.subject, time);
+});
+
+
+
+
\ No newline at end of file
diff --git a/layouts/partials/doc/subscribe_async.html b/layouts/partials/doc/subscribe_async.html
new file mode 100644
index 00000000..310d0937
--- /dev/null
+++ b/layouts/partials/doc/subscribe_async.html
@@ -0,0 +1,148 @@
+
+
+
nc, err := nats.Connect("demo.nats.io")
+if err != nil {
+ log.Fatal(err)
+}
+defer nc.Close()
+
+// Use a WaitGroup to wait for a message to arrive
+wg := sync.WaitGroup{}
+wg.Add(1)
+
+// Subscribe
+if _, err := nc.Subscribe("updates", func(m *nats.Msg) {
+ wg.Done()
+}); err != nil {
+ log.Fatal(err)
+}
+
+// Wait for a message to come in
+wg.Wait()
+
+// Close the connection
+nc.Close()
+
+
+
+
+
Connection nc = Nats.connect("nats://demo.nats.io:4222");
+
+// Use a latch to wait for a message to arrive
+CountDownLatch latch = new CountDownLatch(1);
+
+// Create a dispatcher and inline message handler
+Dispatcher d = nc.createDispatcher((msg) -> {
+ String str = new String(msg.getData(), StandardCharsets.UTF_8);
+ System.out.println(str);
+ latch.countDown();
+});
+
+// Subscribe
+d.subscribe("updates");
+
+// Wait for a message to come in
+latch.await();
+
+// Close the connection
+nc.close();
+
\ No newline at end of file
diff --git a/layouts/partials/doc/subscribe_json.html b/layouts/partials/doc/subscribe_json.html
new file mode 100644
index 00000000..5cb7f6e6
--- /dev/null
+++ b/layouts/partials/doc/subscribe_json.html
@@ -0,0 +1,197 @@
+
+
+
require 'nats/client'
+require 'json'
+
+NATS.start(servers:["nats://127.0.0.1:4222"]) do |nc|
+ nc.subscribe("updates") do |msg|
+ m = JSON.parse(msg)
+
+ # {"symbol"=>"GOOG", "price"=>12}
+ p m
+ end
+end
+
\ No newline at end of file
diff --git a/layouts/partials/doc/subscribe_queue.html b/layouts/partials/doc/subscribe_queue.html
new file mode 100644
index 00000000..87694e73
--- /dev/null
+++ b/layouts/partials/doc/subscribe_queue.html
@@ -0,0 +1,151 @@
+
+
+
nc, err := nats.Connect("demo.nats.io")
+if err != nil {
+ log.Fatal(err)
+}
+defer nc.Close()
+
+// Use a WaitGroup to wait for 10 messages to arrive
+wg := sync.WaitGroup{}
+wg.Add(10)
+
+// Create a queue subscription on "updates" with queue name "workers"
+if _, err := nc.QueueSubscribe("updates", "worker", func(m *nats.Msg) {
+ wg.Done()
+}); err != nil {
+ log.Fatal(err)
+}
+
+// Wait for messages to come in
+wg.Wait()
+
+// Close the connection
+nc.Close()
+
+
+
+
+
Connection nc = Nats.connect("nats://demo.nats.io:4222");
+
+// Use a latch to wait for 10 messages to arrive
+CountDownLatch latch = new CountDownLatch(10);
+
+// Create a dispatcher and inline message handler
+Dispatcher d = nc.createDispatcher((msg) -> {
+ String str = new String(msg.getData(), StandardCharsets.UTF_8);
+ System.out.println(str);
+ latch.countDown();
+});
+
+// Subscribe
+d.subscribe("updates", "workers");
+
+// Wait for a message to come in
+latch.await();
+
+// Close the connection
+nc.close();
+
\ No newline at end of file
diff --git a/layouts/partials/doc/subscribe_star.html b/layouts/partials/doc/subscribe_star.html
new file mode 100644
index 00000000..dfa38489
--- /dev/null
+++ b/layouts/partials/doc/subscribe_star.html
@@ -0,0 +1,201 @@
+
+
+
nc, err := nats.Connect("demo.nats.io")
+if err != nil {
+ log.Fatal(err)
+}
+defer nc.Close()
+
+// Use a WaitGroup to wait for 2 messages to arrive
+wg := sync.WaitGroup{}
+wg.Add(2)
+
+// Subscribe
+if _, err := nc.Subscribe("time.*.east", func(m *nats.Msg) {
+ log.Printf("%s: %s", m.Subject, m.Data)
+ wg.Done()
+}); err != nil {
+ log.Fatal(err)
+}
+
+// Wait for the 2 messages to come in
+wg.Wait()
+
+// Close the connection
+nc.Close()
+
+
+
+
+
Connection nc = Nats.connect("nats://demo.nats.io:4222");
+
+// Use a latch to wait for 2 messages to arrive
+CountDownLatch latch = new CountDownLatch(2);
+
+// Create a dispatcher and inline message handler
+Dispatcher d = nc.createDispatcher((msg) -> {
+ String subject = msg.getSubject();
+ String str = new String(msg.getData(), StandardCharsets.UTF_8);
+ System.out.println(subject + ": " + str);
+ latch.countDown();
+});
+
+// Subscribe
+d.subscribe("time.*.east");
+
+// Wait for messages to come in
+latch.await();
+
+// Close the connection
+nc.close();
+
+
+
+
+
nc.subscribe('time.us.*', (msg, reply, subject) => {
+ // converting timezones correctly in node requires a library
+ // this doesn't take into account *many* things.
+ let time = "";
+ switch (subject) {
+ case 'time.us.east':
+ time = new Date().toLocaleTimeString("en-us", {timeZone: "America/New_York"});
+ break;
+ case 'time.us.central':
+ time = new Date().toLocaleTimeString("en-us", {timeZone: "America/Chicago"});
+ break;
+ case 'time.us.mountain':
+ time = new Date().toLocaleTimeString("en-us", {timeZone: "America/Denver"});
+ break;
+ case 'time.us.west':
+ time = new Date().toLocaleTimeString("en-us", {timeZone: "America/Los_Angeles"});
+ break;
+ default:
+ time = "I don't know what you are talking about Willis";
+ }
+ t.log(subject, time);
+});
+
+
+
+
+
nc = NATS()
+
+await nc.connect(servers=["nats://demo.nats.io:4222"])
+
+# Use queue to wait for 2 messages to arrive
+queue = asyncio.Queue()
+async def cb(msg):
+ await queue.put_nowait(msg)
+
+await nc.subscribe("time.*.east", cb=cb)
+
+# Send 2 messages and wait for them to come in
+await nc.publish("time.A.east", b'A')
+await nc.publish("time.B.east", b'B')
+
+msg_A = await queue.get()
+msg_B = await queue.get()
+
+print("Msg A:", msg_A)
+print("Msg B:", msg_B)
+
+
+
+
+
+
require 'nats/client'
+require 'fiber'
+
+NATS.start(servers:["nats://127.0.0.1:4222"]) do |nc|
+ Fiber.new do
+ f = Fiber.current
+
+ nc.subscribe("time.*.east") do |msg, reply|
+ f.resume Time.now
+ end
+
+ nc.publish("time.A.east", "A")
+ nc.publish("time.B.east", "B")
+
+ # Use the response
+ msg_A = Fiber.yield
+ puts "Msg A: #{msg_A}"
+
+ msg_B = Fiber.yield
+ puts "Msg B: #{msg_B}"
+
+ end.resume
+end
+
+
+
+
+
+
await nc.subscribe('time.us.*', (err, msg) => {
+ // converting timezones correctly in node requires a library
+ // this doesn't take into account *many* things.
+ let time = "";
+ switch (msg.subject) {
+ case 'time.us.east':
+ time = new Date().toLocaleTimeString("en-us", {timeZone: "America/New_York"});
+ break;
+ case 'time.us.central':
+ time = new Date().toLocaleTimeString("en-us", {timeZone: "America/Chicago"});
+ break;
+ case 'time.us.mountain':
+ time = new Date().toLocaleTimeString("en-us", {timeZone: "America/Denver"});
+ break;
+ case 'time.us.west':
+ time = new Date().toLocaleTimeString("en-us", {timeZone: "America/Los_Angeles"});
+ break;
+ default:
+ time = "I don't know what you are talking about Willis";
+ }
+ console.log(msg.subject, time);
+});
+
+
+
+
\ No newline at end of file
diff --git a/layouts/partials/doc/subscribe_sync.html b/layouts/partials/doc/subscribe_sync.html
new file mode 100644
index 00000000..c62292f2
--- /dev/null
+++ b/layouts/partials/doc/subscribe_sync.html
@@ -0,0 +1,108 @@
+
+
+
Connection nc = Nats.connect("nats://demo.nats.io:4222");
+
+// Subscribe
+Subscription sub = nc.subscribe("updates");
+
+// Read a message
+Message msg = sub.nextMessage(Duration.ZERO);
+
+String str = new String(msg.getData(), StandardCharsets.UTF_8);
+System.out.println(str);
+
+// Close the connection
+nc.close();
+
+
+
+
+
// node-nats subscriptions are always async.
+
+
+
+
+
# Asyncio NATS client currently does not have a sync subscribe API
+
+
+
+
+
# The Ruby NATS client subscriptions are all async.
+
+
+
+
+
// ts-nats subscriptions are always async.
+
+
+
+
\ No newline at end of file
diff --git a/layouts/partials/doc/subscribe_w_reply.html b/layouts/partials/doc/subscribe_w_reply.html
new file mode 100644
index 00000000..45d9645f
--- /dev/null
+++ b/layouts/partials/doc/subscribe_w_reply.html
@@ -0,0 +1,170 @@
+
+
+
nc, err := nats.Connect("demo.nats.io")
+if err != nil {
+ log.Fatal(err)
+}
+defer nc.Close()
+
+// Subscribe
+sub, err := nc.SubscribeSync("time")
+if err != nil {
+ log.Fatal(err)
+}
+
+// Read a message
+msg, err := sub.NextMsg(10 * time.Second)
+if err != nil {
+ log.Fatal(err)
+}
+
+// Get the time
+timeAsBytes := []byte(time.Now().String())
+
+// Send the time
+nc.Publish(msg.Reply, timeAsBytes)
+
+// Flush and close the connection
+nc.Flush()
+nc.Close()
+
+
+
+
+
Connection nc = Nats.connect("nats://demo.nats.io:4222");
+
+// Subscribe
+Subscription sub = nc.subscribe("time");
+
+// Read a message
+Message msg = sub.nextMessage(Duration.ZERO);
+
+// Get the time
+Calendar cal = Calendar.getInstance();
+SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
+byte[] timeAsBytes = sdf.format(cal.getTime()).getBytes(StandardCharsets.UTF_8);
+
+// Send the time
+nc.publish(msg.getReplyTo(), timeAsBytes);
+
+// Flush and close the connection
+nc.flush(Duration.ZERO);
+nc.close();
+
+
+
+
+
// set up a subscription to process a request
+nc.subscribe('time', (msg, reply) => {
+ if (msg.reply) {
+ nc.publish(msg.reply, new Date().toLocaleTimeString());
+ }
+});
+
require 'nats/client'
+require 'fiber'
+
+NATS.start(servers:["nats://127.0.0.1:4222"]) do |nc|
+ Fiber.new do
+ f = Fiber.current
+
+ nc.subscribe("time") do |msg, reply|
+ f.resume Time.now
+ end
+
+ nc.publish("time", 'What is the time?', NATS.create_inbox)
+
+ # Use the response
+ msg = Fiber.yield
+ puts "Reply: #{msg}"
+
+ end.resume
+end
+
+
+
+
+
+
// set up a subscription to process a request
+await nc.subscribe('time', (err, msg) => {
+ if (msg.reply) {
+ nc.publish(msg.reply, new Date().toLocaleTimeString());
+ } else {
+ t.log('got a request for the time, but no reply subject was set.');
+ }
+});
+
+
+
+
\ No newline at end of file
diff --git a/layouts/partials/doc/unsubscribe.html b/layouts/partials/doc/unsubscribe.html
new file mode 100644
index 00000000..6b03a3c2
--- /dev/null
+++ b/layouts/partials/doc/unsubscribe.html
@@ -0,0 +1,176 @@
+
+
+
Connection nc = Nats.connect("nats://demo.nats.io:4222");
+Dispatcher d = nc.createDispatcher((msg) -> {
+ String str = new String(msg.getData(), StandardCharsets.UTF_8);
+ System.out.println(str);
+});
+
+// Sync Subscription
+Subscription sub = nc.subscribe("updates");
+sub.unsubscribe();
+
+// Async Subscription
+d.subscribe("updates");
+d.unsubscribe("updates");
+
+// Close the connection
+nc.close();
+
+
+
+
+
// set up a subscription to process a request
+let sub = nc.subscribe(NATS.createInbox(), (msg, reply) => {
+ if (msg.reply) {
+ nc.publish(reply, new Date().toLocaleTimeString());
+ }
+});
+
+// without arguments the subscription will cancel when the server receives it
+// you can also specify how many messages are expected by the subscription
+nc.unsubscribe(sub);
+
require 'nats/client'
+require 'fiber'
+
+NATS.start(servers:["nats://127.0.0.1:4222"]) do |nc|
+ Fiber.new do
+ f = Fiber.current
+
+ sid = nc.subscribe("time") do |msg, reply|
+ f.resume Time.now
+ end
+
+ nc.publish("time", 'What is the time?', NATS.create_inbox)
+
+ # Use the response
+ msg = Fiber.yield
+ puts "Reply: #{msg}"
+
+ nc.unsubscribe(sid)
+
+ # Won't be received
+ nc.publish("time", 'What is the time?', NATS.create_inbox)
+
+ end.resume
+end
+
+
+
+
+
+
// set up a subscription to process a request
+let sub = await nc.subscribe(createInbox(), (err, msg) => {
+ if (msg.reply) {
+ nc.publish(msg.reply, new Date().toLocaleTimeString());
+ } else {
+ t.log('got a request for the time, but no reply subject was set.');
+ }
+});
+
+// without arguments the subscription will cancel when the server receives it
+// you can also specify how many messages are expected by the subscription
+sub.unsubscribe();
+
+
+
+
\ No newline at end of file
diff --git a/layouts/partials/doc/unsubscribe_auto.html b/layouts/partials/doc/unsubscribe_auto.html
new file mode 100644
index 00000000..8721e87c
--- /dev/null
+++ b/layouts/partials/doc/unsubscribe_auto.html
@@ -0,0 +1,175 @@
+
+
+
Connection nc = Nats.connect("nats://demo.nats.io:4222");
+Dispatcher d = nc.createDispatcher((msg) -> {
+ String str = new String(msg.getData(), StandardCharsets.UTF_8);
+ System.out.println(str);
+});
+
+// Sync Subscription
+Subscription sub = nc.subscribe("updates");
+sub.unsubscribe(1);
+
+// Async Subscription
+d.subscribe("updates");
+d.unsubscribe("updates", 1);
+
+// Close the connection
+nc.close();
+
+
+
+
+
// `max` specifies the number of messages that the server will forward.
+// The server will auto-cancel.
+let opts = {max: 10};
+let sub = nc.subscribe(NATS.createInbox(), opts, (msg) => {
+ t.log(msg);
+});
+
+// another way after 10 messages
+let sub2 = nc.subscribe(NATS.createInbox(), (err, msg) => {
+ t.log(msg.data);
+});
+// if the subscription already received 10 messages, the handler
+// won't get any more messages
+nc.unsubscribe(sub2, 10);
+
require 'nats/client'
+require 'fiber'
+
+NATS.start(servers:["nats://127.0.0.1:4222"]) do |nc|
+ Fiber.new do
+ f = Fiber.current
+
+ nc.subscribe("time", max: 1) do |msg, reply|
+ f.resume Time.now
+ end
+
+ nc.publish("time", 'What is the time?', NATS.create_inbox)
+
+ # Use the response
+ msg = Fiber.yield
+ puts "Reply: #{msg}"
+
+ # Won't be received
+ nc.publish("time", 'What is the time?', NATS.create_inbox)
+
+ end.resume
+end
+
+
+
+
+
+
// `max` specifies the number of messages that the server will forward.
+// The server will auto-cancel.
+let opts = {max: 10};
+let sub = await nc.subscribe(createInbox(), (err, msg) => {
+ t.log(msg.data);
+}, opts);
+
+// another way after 10 messages
+let sub2 = await nc.subscribe(createInbox(), (err, msg) => {
+ t.log(msg.data);
+});
+// if the subscription already received 10 messages, the handler
+// won't get any more messages
+sub2.unsubscribe(10);
+
+
+
+
\ No newline at end of file
diff --git a/layouts/partials/doc/wildcard_tester.html b/layouts/partials/doc/wildcard_tester.html
new file mode 100644
index 00000000..2ae72506
--- /dev/null
+++ b/layouts/partials/doc/wildcard_tester.html
@@ -0,0 +1,142 @@
+
+
+