// This will test request semantics across a route to queues func TestRequestsAcrossRoutesToQueues(t *testing.T) { srvA, srvB, optsA, optsB := runServers(t) defer srvA.Shutdown() defer srvB.Shutdown() urlA := fmt.Sprintf("nats://%s:%d/", optsA.Host, optsA.Port) urlB := fmt.Sprintf("nats://%s:%d/", optsB.Host, optsB.Port) nc1, err := nats.Connect(urlA) if err != nil { t.Fatalf("Failed to create connection for nc1: %v\n", err) } defer nc1.Close() nc2, err := nats.Connect(urlB) if err != nil { t.Fatalf("Failed to create connection for nc2: %v\n", err) } defer nc2.Close() ec1, _ := nats.NewEncodedConn(nc1, nats.JSON_ENCODER) ec2, _ := nats.NewEncodedConn(nc2, nats.JSON_ENCODER) response := []byte("I will help you") // Connect one responder to srvA nc1.QueueSubscribe("foo-req", "booboo", func(m *nats.Msg) { nc1.Publish(m.Reply, response) }) // Make sure the route and the subscription are propagated. nc1.Flush() // Connect the other responder to srvB nc2.QueueSubscribe("foo-req", "booboo", func(m *nats.Msg) { nc2.Publish(m.Reply, response) }) var resp string for i := 0; i < 100; i++ { if err := ec2.Request("foo-req", i, &resp, 100*time.Millisecond); err != nil { t.Fatalf("Received an error on Request test [%d]: %s", i, err) } } for i := 0; i < 100; i++ { if err := ec1.Request("foo-req", i, &resp, 100*time.Millisecond); err != nil { t.Fatalf("Received an error on Request test [%d]: %s", i, err) } } }
// Connect just connects you to nats, no fuss. func Connect() (*Uplink, error) { nc, err := nats.Connect(*natsServer) if err != nil { return nil, err } c, err := nats.NewEncodedConn(nc, nats.JSON_ENCODER) if err != nil { return nil, err } id := uuid.New() u := &Uplink{ EncodedConn: c, Logger: log.New(os.Stdout, id+" ", log.LstdFlags), ID: id, Nats: nc, } _, err = c.Subscribe(u.ID+":ping", func(subj, reply string, msg string) { c.Publish(reply, "pong") }) if err != nil { return nil, err } return u, nil }
func NewVindaluSubscriber(server string, logger *log.Logger) (vs *VindaluSubscriber, err error) { vs = &VindaluSubscriber{} opts := nats.DefaultOptions opts.Servers, err = GetNatsServers(server) if err != nil { return } if vs.conn, err = opts.Connect(); err != nil { return } logger.Debug.Printf("nats client connected to: %v!\n", vs.conn.ConnectedUrl()) vs.conn.Opts.ReconnectedCB = func(nc *nats.Conn) { logger.Debug.Printf("nats client reconnected to: %v!\n", nc.ConnectedUrl()) } vs.conn.Opts.DisconnectedCB = func(_ *nats.Conn) { logger.Debug.Printf("nats client disconnected!\n") } vs.enConn, err = nats.NewEncodedConn(vs.conn, nats.JSON_ENCODER) return }
func NewJsonEncodedConn(tl test.TestLogger) *nats.EncodedConn { ec, err := nats.NewEncodedConn(test.NewDefaultConnection(tl), nats.JSON_ENCODER) if err != nil { tl.Fatalf("Failed to create an encoded connection: %v\n", err) } return ec }
func NewEConn(t *testing.T) *nats.EncodedConn { ec, err := nats.NewEncodedConn(test.NewConnection(t, TEST_PORT), nats.DEFAULT_ENCODER) if err != nil { t.Fatalf("Failed to create an encoded connection: %v\n", err) } return ec }
func BenchmarkPublishSpeedViaChan(b *testing.B) { b.StopTimer() s := RunDefaultServer() defer s.Shutdown() nc, err := nats.Connect(nats.DefaultURL) if err != nil { b.Fatalf("Could not connect: %v\n", err) } ec, err := nats.NewEncodedConn(nc, nats.DEFAULT_ENCODER) defer ec.Close() ch := make(chan int32, 1024) if err := ec.BindSendChan("foo", ch); err != nil { b.Fatalf("Failed to bind to a send channel: %v\n", err) } b.StartTimer() num := int32(22) for i := 0; i < b.N; i++ { ch <- num } // Make sure they are all processed. nc.Flush() b.StopTimer() }
func NewGobEncodedConn(t *testing.T) *nats.EncodedConn { ec, err := nats.NewEncodedConn(test.NewDefaultConnection(t), nats.GOB_ENCODER) if err != nil { t.Fatalf("Failed to create an encoded connection: %v\n", err) } return ec }
func NewProtoEncodedConn(tl test.TestLogger) *nats.EncodedConn { ec, err := nats.NewEncodedConn(test.NewConnection(tl, TEST_PORT), protobuf.PROTOBUF_ENCODER) if err != nil { tl.Fatalf("Failed to create an encoded connection: %v\n", err) } return ec }
func NewProtoEncodedConn(t *testing.T) *nats.EncodedConn { ec, err := nats.NewEncodedConn(NewConn(), PROTOBUF_ENCODER) if err != nil { t.Fatalf("Failed to create an encoded connection: %v\n", err) } return ec }
func NewEConn(t tLogger) *nats.EncodedConn { ec, err := nats.NewEncodedConn(NewDefaultConnection(t), nats.DEFAULT_ENCODER) if err != nil { t.Fatalf("Failed to create an encoded connection: %v\n", err) } return ec }
func runLogger() { log.Printf("Starting worker") nc, err := nats.Connect("nats://localhost:4222") if err != nil { log.Printf("Failed to connect to message queue: %s", err) return } c, err := nats.NewEncodedConn(nc, nats.JSON_ENCODER) if err != nil { log.Printf("Failed to create encoded connection for message queue: %s", err) return } log.Printf("Connected") subject := "cast" subscription, err := c.Subscribe(subject, func(s string) { log.Printf("Received a message: %v", s) }) if err != nil { log.Printf("Failed to subscribe to subject %s: %v", subject, err) return } log.Printf("Listening for messages on %s", subscription.Subject) }
func (s *gnatsdSuite) aTestSerivce() { service := &gnatsdService{} port, err := service.Start() s.NoError(err, "start service error") defer service.Stop() nc, err := nats.Connect(fmt.Sprintf("nats://localhost:%d", port)) s.NoError(err, "create conn error") c, err := nats.NewEncodedConn(nc, nats.JSON_ENCODER) s.NoError(err, "create encoded conn error") defer c.Close() testText := "Hello World" testTopic := "foo" received := false // Simple Async Subscriber c.Subscribe(testTopic, func(reply string) { s.Equal(testText, reply, "reply inconsistent") received = true }) // Simple Publisher err = c.Publish(testTopic, testText) s.NoError(err, "publish msg error") time.Sleep(3 * time.Second) s.True(received, "not recevied any msgs") }
func main() { flag.Parse() fmt.Println("topic is " + topic) fmt.Println("message is " + message) ticker := time.NewTicker(4 * time.Second) _ = <-ticker.C nc, _ := nats.Connect(nats.DefaultURL) c, _ := nats.NewEncodedConn(nc, nats.JSON_ENCODER) defer c.Close() if c == nil { fmt.Printf("nats error: fail to connect.\n") os.Exit(0) } for { err := c.LastError() if err != nil { fmt.Printf("nats error: %s", err.Error()) break } _ = <-ticker.C err = c.Publish(topic, message) if err != nil { fmt.Printf("publish err: %s", err.Error()) os.Exit(0) } fmt.Printf("public topic %s with content %s\n", topic, message) } }
func TestBasicReconnectFunctionality(t *testing.T) { ts := startReconnectServer(t) ch := make(chan bool) opts := reconnectOpts nc, _ := opts.Connect() ec, err := nats.NewEncodedConn(nc, nats.DEFAULT_ENCODER) if err != nil { t.Fatalf("Failed to create an encoded connection: %v\n", err) } testString := "bar" ec.Subscribe("foo", func(s string) { if s != testString { t.Fatal("String doesn't match") } ch <- true }) ec.Flush() ts.Shutdown() // server is stopped here... dch := make(chan bool) opts.DisconnectedCB = func(_ *nats.Conn) { dch <- true } WaitTime(dch, 500*time.Millisecond) if err := ec.Publish("foo", testString); err != nil { t.Fatalf("Failed to publish message: %v\n", err) } ts = startReconnectServer(t) defer ts.Shutdown() if err := ec.FlushTimeout(5 * time.Second); err != nil { t.Fatalf("Error on Flush: %v", err) } if e := Wait(ch); e != nil { t.Fatal("Did not receive our message") } // This test fails sometimes on Travis with '0 vs 1', which is weird. // If we are here, that means that the message published while we // were disconnected has been properly flushed and we have receive that // message. Conn.Reconnects is updated *before* the content of the // pending buffer is flushed, so it cannot be 0 at this point... expectedReconnectCount := uint64(1) reconnectCount := ec.Conn.Stats().Reconnects if reconnectCount != expectedReconnectCount { t.Fatalf("Reconnect count incorrect: %d vs %d\n", reconnectCount, expectedReconnectCount) } nc.Close() }
func runResponder() { log.Printf("Starting responder") nc, err := nats.Connect("nats://localhost:4222") if err != nil { log.Printf("Failed to connect to message queue: %s", err) return } c, err := nats.NewEncodedConn(nc, nats.JSON_ENCODER) if err != nil { log.Printf("Failed to create encoded connection for message queue: %s", err) return } log.Printf("Connected") subject := "call" subscription, err := c.Subscribe(subject, func(subject string, replyTo string, s string) { log.Printf("Received a message: %v", s) c.Publish(replyTo, "pong") }) if err != nil { log.Printf("Failed to subscribe to subject %s: %v", subject, err) return } log.Printf("Responding to messages on %s", subscription.Subject) }
func main() { c = nconfig.Load() qAddr := c.GetString(nconfig.KEY_QUEUE_ADDR) n, e := nats.Connect(qAddr) if e != nil { panic(e) } conn, err := nats.NewEncodedConn(n, nats.JSON_ENCODER) if err != nil { panic(err) } conn.Subscribe("realtime-jobs", jobsHandler) log.Info("Connected to NATS on " + qAddr) http.HandleFunc("/register", func(w http.ResponseWriter, r *http.Request) { conn, err := upgrader.Upgrade(w, r, nil) if err != nil { panic(err) return } connections = append(connections, conn) }) port := c.GetString(nconfig.KEY_BROKER_PORT) log.Info("Starting WS service on port " + port) http.ListenAndServe(port, nil) }
func NewElectronConn(opt *nats.Options) (ec *ElectronConn, err error) { var nc *nats.Conn if opt == nil { nc, err = nats.Connect(nats.DefaultURL) } else { nc, err = opt.Connect() } if err != nil { return nil, err } ec = &ElectronConn{conn: nc} f := func(m *nats.Msg) { ID := atomic.AddUint32(&ec.genID, 1) if err := nc.Publish(m.Reply, []byte(fmt.Sprintf("%d", ID))); err != nil { logrus.Error(err) return } ec.Lock() ec.clients = append(ec.clients, ID) ec.Unlock() } if _, err = nc.Subscribe("register", f); err != nil { nc.Close() return nil, fmt.Errorf("nats: %v", err) } if ec.jsonConn, err = nats.NewEncodedConn(nc, "json"); err != nil { nc.Close() return nil, fmt.Errorf("nats: %v", err) } return }
func (out *natsOut) Handle(ctx context.Context, prev <-chan ql.Line, config map[string]interface{}) error { log.Log(ctx).Debug("Starting output handler", "handler", "nats") url, ok := config["url"].(string) if !ok || url == "" { log.Log(ctx).Error("Could not create nats output, no url defined") return fmt.Errorf("Could not create nats output, no url defined") } opts := nats.DefaultOptions opts.Url = url servers, ok := config["servers"].([]string) if ok { opts.Servers = servers } publish, ok := config["publish"].(string) if !ok || publish == "" { log.Log(ctx).Error("Could not create nats output, no publish defined") return fmt.Errorf("Could not create nats output, no publish defined") } encoding, ok := config["encoding"].(string) if !ok || encoding == "" { encoding = nats.JSON_ENCODER } nc, err := opts.Connect() if err != nil { log.Log(ctx).Error("Error connecting to nats url", "url", url, "error", err) return err } c, err := nats.NewEncodedConn(nc, encoding) if err != nil { log.Log(ctx).Error("Error creating nats connection", "error", err) return err } go func() { defer c.Close() for { select { case line := <-prev: err = c.Publish(publish, line) if err != nil { log.Log(ctx).Error("Error publishing to nats connection", "error", err) } case <-ctx.Done(): return } } }() return nil }
func main() { nc, _ = nats.Connect(nats.DefaultURL) c, _ = nats.NewEncodedConn(nc, nats.JSON_ENCODER) defer c.Close() m := setupRouter() m.Run() }
// Create a new instance of the driver. The NATS encoded connection // will use json and the options passed in. func NewNatsRpc(opts *nats.Options) (*NatsRpcDriver, error) { nc, err := opts.Connect() ec, _ := nats.NewEncodedConn(nc, "json") if err != nil { return nil, err } return &NatsRpcDriver{ec: ec}, nil }
func main() { // Declare the subject to use for publishing/subscribing. const subject = "test" // Connect to the local nats server. rawConn, err := nats.Connect(nats.DefaultURL) if err != nil { log.Println("Unable to connect to NATS") return } // Create an encoded connection conn, err := nats.NewEncodedConn(rawConn, nats.JSON_ENCODER) if err != nil { log.Println("Unable to create an encoded connection") return } // Make and bind a channel to receiving user values. recv := make(chan user) subRecv, err := conn.BindRecvChan(subject, recv) if err != nil { log.Println("Unable to bind the receive channel") return } // Make and bind a channel to send user values. send := make(chan user) if err := conn.BindSendChan(subject, send); err != nil { log.Println("Unable to bind the send channel") return } // Create a value of type user. u1 := user{ Name: "bill", Email: "*****@*****.**", } // Send the value to the message bus. send <- u1 // Receiving the value from the message bus. u2 := <-recv // Display the user. log.Println("Received a user:"******"Error unsubscribing from the receive subscription:", err) return } // Close the connection to the NATS server. conn.Close() }
func TestBasicReconnectFunctionality(t *testing.T) { ts := startReconnectServer(t) ch := make(chan bool) dch := make(chan bool) opts := reconnectOpts opts.DisconnectedCB = func(_ *nats.Conn) { dch <- true } nc, _ := opts.Connect() ec, err := nats.NewEncodedConn(nc, nats.DEFAULT_ENCODER) if err != nil { t.Fatalf("Failed to create an encoded connection: %v\n", err) } testString := "bar" ec.Subscribe("foo", func(s string) { if s != testString { t.Fatal("String doesn't match") } ch <- true }) ec.Flush() ts.Shutdown() // server is stopped here... if err := Wait(dch); err != nil { t.Fatalf("Did not get the disconnected callback on time\n") } if err := ec.Publish("foo", testString); err != nil { t.Fatalf("Failed to publish message: %v\n", err) } ts = startReconnectServer(t) defer ts.Shutdown() if err := ec.FlushTimeout(5 * time.Second); err != nil { t.Fatalf("Error on Flush: %v", err) } if e := Wait(ch); e != nil { t.Fatal("Did not receive our message") } expectedReconnectCount := uint64(1) reconnectCount := ec.Conn.Stats().Reconnects if reconnectCount != expectedReconnectCount { t.Fatalf("Reconnect count incorrect: %d vs %d\n", reconnectCount, expectedReconnectCount) } nc.Close() }
func Connect(chanLen int) *Conn { natsopts := getNatsOptions(chanLen) c, err := natsopts.Connect() if err != nil { panic(err) } ec, err := nats.NewEncodedConn(c, "gob") return &Conn{*ec} }
// EstablishJSONEncodedConnection is a blocking way to create and establish // JSON-encoded connection to the default NATS server. The function will // only return after a timeout has reached or a connection has been // established. It returns the JSON-encoded connection and and any timeout // error encountered. func EstablishJSONEncodedConnection(timeout *time.Duration) (*EncodedConnection, error) { nc, err := EstablishConnection(timeout) if err != nil { return nil, err } ec, err := nats.NewEncodedConn(nc.Conn, nats.JSON_ENCODER) if err != nil { return nil, err } return &EncodedConnection{ec}, nil }
// NewJSONEncodedConnection creates a JSON-encoded connetion to the // default NATS server and tries to establish the connection. It // returns the JSON-encoded connection and any connection error // encountered. func NewJSONEncodedConnection() (*EncodedConnection, error) { nc, err := NewConnection() if err != nil { return nil, err } ec, err := nats.NewEncodedConn(nc.Conn, nats.JSON_ENCODER) if err != nil { return nil, err } return &EncodedConnection{ec}, nil }
func TestConstructorErrs(t *testing.T) { s := test.RunDefaultServer() defer s.Shutdown() c := test.NewDefaultConnection(t) _, err := nats.NewEncodedConn(nil, "default") if err == nil { t.Fatal("Expected err for nil connection") } _, err = nats.NewEncodedConn(c, "foo22") if err == nil { t.Fatal("Expected err for bad encoder") } c.Close() _, err = nats.NewEncodedConn(c, "default") if err == nil { t.Fatal("Expected err for closed connection") } }
func init() { nc, _ := nats.Connect(nats.DefaultURL) c, err := nats.NewEncodedConn(nc, nats.DEFAULT_ENCODER) if err != nil { log.Print("mq init error") } else { mq.conn = c } //handle http publish message http.Handle("/publish", &httpPublisher{}) }
// Start subscribing to subjects/routes. func (natsOpts *NatsOptions) Connect() (natsObj *Nats, err error) { if len(natsOpts.Name) == 0 { panic("Must set Name in NatsOptions") } con, err := natsOpts.Options.Connect() if err != nil { return } natsObj = &Nats{Opts: natsOpts} natsObj.EncCon, err = nats.NewEncodedConn(con, natsOpts.encoding) return }
// EncodedConn can publish virtually anything just // by passing it in. The encoder will be used to properly // encode the raw Go type func ExampleEncodedConn_Publish() { nc, _ := nats.Connect(nats.DefaultURL) c, _ := nats.NewEncodedConn(nc, "json") defer c.Close() type person struct { Name string Address string Age int } me := &person{Name: "derek", Age: 22, Address: "85 Second St"} c.Publish("hello", me) }
func (a *Agent) register(addr string) error { if a.UID == "" { return errors.New("UID can't be empty") } var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(a); err != nil { return err } // url.Parse instead of just appending will inform // about errors when addr or path is malformed. l, err := url.Parse(addr + agentsAPIPath) if err != nil { return err } resp, err := http.Post(l.String(), "application/json", &buf) if err != nil { return err } defer resp.Body.Close() var t struct { NatsURL string `json:"nats_url"` } dec := json.NewDecoder(resp.Body) if err := dec.Decode(&t); err != nil { return err } // Override the obtained NATS address with the one obtained from the command line flag. var naddr string if *flagNATSAddr == "" { naddr = t.NatsURL } else { naddr = *flagNATSAddr } nc, err := nats.Connect(naddr) if err != nil { return err } // TODO: Should we return the conn instead of using a global? natsEncConn, err = nats.NewEncodedConn(nc, "json") if err != nil { return err } return nil }