Connect to NATS server?

I am trying to make a Publish/Subscribe Server using NATS. First step is to connect to the NATS server, but found no working code in the documentation. Here is what I have tried:

package main

import (
	"github.com/nats-io/nats.go"
	"fmt"
)

func main() {
	// Connect to a server
	nc, err := nats.Connect("tls://nats.go4webdev.org:4222")
    if err!=nil{
		fmt.Println(err)
	}
	fmt.Println(nc)
}

No matter if I instead call
nc, err := nats.Connect("nats://nats.go4webdev.org:4222")

The answer I get from the server:

dial tcp 104.21.65.248:4222: i/o timeout

If I omit the port number, I get this error:

dial tcp [2606:4700:3031::ac43:c3d0]:4222: connect: no route to host

The NATS server is up and running. A port scan shows this:

Port Scanning host: 94.237.X.X
Open TCP Port: 4222

The NATS server on Cloudflare Flexible SSL (proxy)

I run the command service nats status:

> Oct 08 16:02:24 go4webdev.org nats-server[59191]: [59191] 2022/10/08 16:02:24.583853 [ERR] 194.218.x.x:50015 - cid:10 - Client parser ERROR, state=0, i=0: proto='"\x16\x03\x01\x00\xb9\x01\x00\x00\xb5\x03\x01B\xe7\x19\xaa\f\x85\xaf\x81 \xf3\xa6E:)\x88\x93\xe5oKe\x9a"...'
> Oct 08 16:14:00 go4webdev.org nats-server[59191]: [59191] 2022/10/08 16:14:00.470805 [ERR] 127.0.0.1:51756 - cid:12 - Client parser ERROR, state=0, i=0: proto='"GET / HTTP/1.0\r\nHost: localhost:"...'
> Oct 08 16:16:19 go4webdev.org nats-server[59191]: [59191] 2022/10/08 16:16:19.501242 [ERR] 127.0.0.1:51758 - cid:13 - Client parser ERROR, state=0, i=0: proto='"GET / HTTP/1.0\r\nHost: localhost:"...'
> Oct 08 16:18:44 go4webdev.org nats-server[59191]: [59191] 2022/10/08 16:18:44.130856 [ERR] [::1]:41494 - cid:14 - Client parser ERROR, state=0, i=0: proto='"GET / HTTP/1.0\r\nHost: localhost:"...'

Any clue how to connect to the NATS server? What am I doing wrong?

Did you tried the examples from the github page of the project?

This is the example from there:

// Connect to NATS
nc, _ := nats.Connect(nats.DefaultURL)

nats: no servers available for connection

Which means 127.0.0.1:4222 AFAIK. But the client is on my desktop and a the NATS server on a remote server. Or did I miss something?

I started a local NATS server, and it seems that some connection is established.

&{{0 0 0 0 0} {{0 0} 0 0 0 0} { <nil> [nats://127.0.0.1:4222] false false  false false false <nil> true 60 2s <nil> 100ms 1s 2s 30s 0s 2m0s 2 <nil> <nil> <nil> <nil> <nil> 0x1232440 8388608 65536 <nil>  <nil>    <nil> 0xc00012a1e0 <nil> false false <nil> false false  } {{} 8589934592 0} [0xc00013d840] 0xc00013d840 map[127.0.0.1:4222:{}] 0xc000094000 0xc00013d900 0xc00013d8c0 0xc000098000 {NCBYMQE5VXE7YMZ23UDM5TEVVRLKFVVZ5GNEIP2ULVK2LTCJHIANVJGF NCBYMQE5VXE7YMZ23UDM5TEVVRLKFVVZ5GNEIP2ULVK2LTCJHIANVJGF 1 2.9.2 0.0.0.0 4222 true false false false 1048576 17 127.0.0.1   [] false} 0 {{0 0} 0 0 0 0} map[] 0xc00014c400 [] [72 80 85 66 32 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] 1 false <nil> 0xc0001a4000 0xc0000ca000 0 false 0xc000098060 false   0  <nil> map[] <nil> map[]}

But I still can interact with the server. No response. Here is the code used.

package main

import (
	"fmt"
	"github.com/nats-io/nats.go"
	"time"
)

func main() {
	// Connect to a server
	nc, err := nats.Connect(nats.DefaultURL)
	if err != nil {
		fmt.Println("no connection")
		fmt.Println(err)
	}
	fmt.Println(nc)
	defer nc.Close()

	// Simple Publisher
	nc.Publish("foo", []byte("Hello World"))

	// Simple Async Subscriber
	nc.Subscribe("foo", func(msg *nats.Msg) {
		fmt.Println("subscribe")
		fmt.Printf("Received a message: %s\n", string(msg.Data))
	})

	// Close connection
	nc.Close()
}

  1. How do I know that the connection is OK?
  2. What am I doing wrong as I get no response from the NATS server?

are you sure the NATS server has tls enabled? have you tried nats:// intesad of tls://. keep in mind that using nats:// switches automatically to TLS if it’s enabled

1 Like

I use nats:// in this example, but I do not still understand how it works.
Here are my attempts:

Server is running

./nats-server
[2819] 2022/10/11 16:24:33.375813 [INF] Starting nats-server
[2819] 2022/10/11 16:24:33.375911 [INF]   Version:  2.9.2
[2819] 2022/10/11 16:24:33.375915 [INF]   Git:      [6d81dde]
[2819] 2022/10/11 16:24:33.375920 [INF]   Name:     NDXYJG4CQZMVFASH6GZDSUQ2SY2DXD3NLVIILEQP2YTIP7XWEDHHF7OT
[2819] 2022/10/11 16:24:33.375924 [INF]   ID:       NDXYJG4CQZMVFASH6GZDSUQ2SY2DXD3NLVIILEQP2YTIP7XWEDHHF7OT
[2819] 2022/10/11 16:24:33.377446 [INF] Listening for client connections on 0.0.0.0:4222
[2819] 2022/10/11 16:24:33.378535 [INF] Server is ready

And port scan shows that this is open locally: Open TCP Port: 4222

Running Client

package main

import (
	"fmt"
	"github.com/nats-io/nats.go"
)

func main() {
	// Connect to a server
	nc, err := nats.Connect(nats.DefaultURL)
	if err != nil {
		fmt.Println("no connection")
		fmt.Println(err)
	}
	defer nc.Close()
	fmt.Println("connected? -- no errors reported but not sure")

	// Simple Publisher
	err = nc.Publish("foo", []byte("Hello World"))
	if err != nil {
		fmt.Println("nothing published")
		fmt.Println(err)
	}

	// Simple Async Subscriber
	msg, err := nc.Subscribe("foo", func(msg *nats.Msg) {
		fmt.Println("subscribe--------------------")
		fmt.Println(msg)
		fmt.Println("Received a message: %s\n", string(msg.Data))
	})
	
	if err != nil {
		fmt.Println("nothing subscribed")
		fmt.Println(err)
	}
	fmt.Println("subscribe msg:")
	fmt.Println(msg)

	// Close connection
	//nc.Close()
}

Giving this “errors”

connected? – no errors reported but not sure
subscribe msg:
&{{0 0} 1 foo 0 0 0xc000198000 0x1249a80 false false false 0 0xc00020e000 0 0 0 0 524288 67108864 0}

I find NATS utmost confusing. Is there a better tool that works in a simpler way with PubSub and separate “rooms” or “clients”?

why is confusing? have you followed tutorials on docs.nats.io?
what is your use-case ?

I have followed this “tutorial” and modified to nats.defaultURL

The nats-server is up and running according to this:

[1975] 2022/10/13 10:29:23.246236 [INF] Starting nats-server
[1975] 2022/10/13 10:29:23.246350 [INF]   Version:  2.9.2
[1975] 2022/10/13 10:29:23.246354 [INF]   Git:      [6d81dde]
[1975] 2022/10/13 10:29:23.246357 [INF]   Name:     NBACHDMRCRTQN255JFUU7XDLWSNLVCML7AIDTZWGIG3LGMMSWZETRXD6
[1975] 2022/10/13 10:29:23.246359 [INF]   ID:       NBACHDMRCRTQN255JFUU7XDLWSNLVCML7AIDTZWGIG3LGMMSWZETRXD6
[1975] 2022/10/13 10:29:23.249624 [INF] Listening for client connections on 0.0.0.0:4222
[1975] 2022/10/13 10:29:23.250751 [INF] Server is ready

But when I run the tutorial code I will at least get an error (first time)

2022/10/13 10:44:31 nats: timeout

That is why I think NATS is very confusing. :slight_smile:
Not even their own tutorial works.

My use case is basically to achieve notification that something has happened that is targeted to ME. Nobody else.

Well, Never trust tutorials if you are a newbie :slight_smile:

Here was the code on github:

// Connect to a server
nc, _ := nats.Connect(nats.DefaultURL)

// Simple Publisher
nc.Publish("foo", []byte("Hello World"))

// Simple Async Subscriber
nc.Subscribe("foo", func(m *nats.Msg) {
    fmt.Printf("Received a message: %s\n", string(m.Data))
})

But you must subscribe before you publish…

func main() {
	nc, err := nats.Connect(nats.DefaultURL)
	if err != nil {
		log.Fatal(err)
	}
	defer nc.Close()

	// Subscribe
	sub, err := nc.SubscribeSync("foo")
	if err != nil {
		log.Fatal(err)
	}

	// Simple Publisher
	nc.Publish("foo", []byte("Hello World"))

	// Wait for a message
	msg, err := sub.NextMsg(10 * time.Second)
	if err != nil {
		log.Fatal(err)
	}

	// Use the response
	log.Printf("Reply: %s", msg.Data)
}

2022/10/13 15:48:05 Reply: Hello World

Well the tutorial shows how to subscribe.

In general, unless you don’t use some kind of persistence like Jetstream, all PUB/SUB systems has the issue of late-subscribing. So this means that you cannot receive messages published before you subscribed

1 Like