Golang client for NATS, the cloud native messaging system.

NATS - Go Client

A Go client for the NATS messaging system.

License Apache 2 FOSSA Status Go Report Card Build Status GoDoc Coverage Status

Installation

# Go client
go get github.com/nats-io/nats.go/

# Server
go get github.com/nats-io/nats-server

When using or transitioning to Go modules support:

# Go client latest or explicit version
go get github.com/nats-io/nats.go/@latest
go get github.com/nats-io/nats.go/@v1.10.0

# For latest NATS Server, add /v2 at the end
go get github.com/nats-io/nats-server/v2

# NATS Server v1 is installed otherwise
# go get github.com/nats-io/nats-server

Basic Usage

import nats "github.com/nats-io/nats.go"

// 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))
})

// Responding to a request message
nc.Subscribe("request", func(m *nats.Msg) {
    m.Respond([]byte("answer is 42"))
})

// Simple Sync Subscriber
sub, err := nc.SubscribeSync("foo")
m, err := sub.NextMsg(timeout)

// Channel Subscriber
ch := make(chan *nats.Msg, 64)
sub, err := nc.ChanSubscribe("foo", ch)
msg := <- ch

// Unsubscribe
sub.Unsubscribe()

// Drain
sub.Drain()

// Requests
msg, err := nc.Request("help", []byte("help me"), 10*time.Millisecond)

// Replies
nc.Subscribe("help", func(m *nats.Msg) {
    nc.Publish(m.Reply, []byte("I can help!"))
})

// Drain connection (Preferred for responders)
// Close() not needed if this is called.
nc.Drain()

// Close connection
nc.Close()

Encoded Connections

nc, _ := nats.Connect(nats.DefaultURL)
c, _ := nats.NewEncodedConn(nc, nats.JSON_ENCODER)
defer c.Close()

// Simple Publisher
c.Publish("foo", "Hello World")

// Simple Async Subscriber
c.Subscribe("foo", func(s string) {
    fmt.Printf("Received a message: %s\n", s)
})

// EncodedConn can Publish any raw Go type using the registered Encoder
type person struct {
     Name     string
     Address  string
     Age      int
}

// Go type Subscriber
c.Subscribe("hello", func(p *person) {
    fmt.Printf("Received a person: %+v\n", p)
})

me := &person{Name: "derek", Age: 22, Address: "140 New Montgomery Street, San Francisco, CA"}

// Go type Publisher
c.Publish("hello", me)

// Unsubscribe
sub, err := c.Subscribe("foo", nil)
// ...
sub.Unsubscribe()

// Requests
var response string
err = c.Request("help", "help me", &response, 10*time.Millisecond)
if err != nil {
    fmt.Printf("Request failed: %v\n", err)
}

// Replying
c.Subscribe("help", func(subj, reply string, msg string) {
    c.Publish(reply, "I can help!")
})

// Close connection
c.Close();

New Authentication (Nkeys and User Credentials)

This requires server with version >= 2.0.0

NATS servers have a new security and authentication mechanism to authenticate with user credentials and Nkeys. The simplest form is to use the helper method UserCredentials(credsFilepath).

nc, err := nats.Connect(url, nats.UserCredentials("user.creds"))

The helper methods creates two callback handlers to present the user JWT and sign the nonce challenge from the server. The core client library never has direct access to your private key and simply performs the callback for signing the server challenge. The helper will load and wipe and erase memory it uses for each connect or reconnect.

The helper also can take two entries, one for the JWT and one for the NKey seed file.

nc, err := nats.Connect(url, nats.UserCredentials("user.jwt", "user.nk"))

You can also set the callback handlers directly and manage challenge signing directly.

nc, err := nats.Connect(url, nats.UserJWT(jwtCB, sigCB))

Bare Nkeys are also supported. The nkey seed should be in a read only file, e.g. seed.txt

> cat seed.txt
# This is my seed nkey!
SUAGMJH5XLGZKQQWAWKRZJIGMOU4HPFUYLXJMXOO5NLFEO2OOQJ5LPRDPM

This is a helper function which will load and decode and do the proper signing for the server nonce. It will clear memory in between invocations. You can choose to use the low level option and provide the public key and a signature callback on your own.

opt, err := nats.NkeyOptionFromSeed("seed.txt")
nc, err := nats.Connect(serverUrl, opt)

// Direct
nc, err := nats.Connect(serverUrl, nats.Nkey(pubNkey, sigCB))

TLS

// tls as a scheme will enable secure connections by default. This will also verify the server name.
nc, err := nats.Connect("tls://nats.demo.io:4443")

// If you are using a self-signed certificate, you need to have a tls.Config with RootCAs setup.
// We provide a helper method to make this case easier.
nc, err = nats.Connect("tls://localhost:4443", nats.RootCAs("./configs/certs/ca.pem"))

// If the server requires client certificate, there is an helper function for that too:
cert := nats.ClientCert("./configs/certs/client-cert.pem", "./configs/certs/client-key.pem")
nc, err = nats.Connect("tls://localhost:4443", cert)

// You can also supply a complete tls.Config

certFile := "./configs/certs/client-cert.pem"
keyFile := "./configs/certs/client-key.pem"
cert, err := tls.LoadX509KeyPair(certFile, keyFile)
if err != nil {
    t.Fatalf("error parsing X509 certificate/key pair: %v", err)
}

config := &tls.Config{
    ServerName: 	opts.Host,
    Certificates: 	[]tls.Certificate{cert},
    RootCAs:    	pool,
    MinVersion: 	tls.VersionTLS12,
}

nc, err = nats.Connect("nats://localhost:4443", nats.Secure(config))
if err != nil {
	t.Fatalf("Got an error on Connect with Secure Options: %+v\n", err)
}

Using Go Channels (netchan)

nc, _ := nats.Connect(nats.DefaultURL)
ec, _ := nats.NewEncodedConn(nc, nats.JSON_ENCODER)
defer ec.Close()

type person struct {
     Name     string
     Address  string
     Age      int
}

recvCh := make(chan *person)
ec.BindRecvChan("hello", recvCh)

sendCh := make(chan *person)
ec.BindSendChan("hello", sendCh)

me := &person{Name: "derek", Age: 22, Address: "140 New Montgomery Street"}

// Send via Go channels
sendCh <- me

// Receive via Go channels
who := <- recvCh

Wildcard Subscriptions

// "*" matches any token, at any level of the subject.
nc.Subscribe("foo.*.baz", func(m *Msg) {
    fmt.Printf("Msg received on [%s] : %s\n", m.Subject, string(m.Data));
})

nc.Subscribe("foo.bar.*", func(m *Msg) {
    fmt.Printf("Msg received on [%s] : %s\n", m.Subject, string(m.Data));
})

// ">" matches any length of the tail of a subject, and can only be the last token
// E.g. 'foo.>' will match 'foo.bar', 'foo.bar.baz', 'foo.foo.bar.bax.22'
nc.Subscribe("foo.>", func(m *Msg) {
    fmt.Printf("Msg received on [%s] : %s\n", m.Subject, string(m.Data));
})

// Matches all of the above
nc.Publish("foo.bar.baz", []byte("Hello World"))

Queue Groups

// All subscriptions with the same queue name will form a queue group.
// Each message will be delivered to only one subscriber per queue group,
// using queuing semantics. You can have as many queue groups as you wish.
// Normal subscribers will continue to work as expected.

nc.QueueSubscribe("foo", "job_workers", func(_ *Msg) {
  received += 1;
})

Advanced Usage

// Normally, the library will return an error when trying to connect and
// there is no server running. The RetryOnFailedConnect option will set
// the connection in reconnecting state if it failed to connect right away.
nc, err := nats.Connect(nats.DefaultURL,
    nats.RetryOnFailedConnect(true),
    nats.MaxReconnects(10),
    nats.ReconnectWait(time.Second),
    nats.ReconnectHandler(func(_ *nats.Conn) {
        // Note that this will be invoked for the first asynchronous connect.
    }))
if err != nil {
    // Should not return an error even if it can't connect, but you still
    // need to check in case there are some configuration errors.
}

// Flush connection to server, returns when all messages have been processed.
nc.Flush()
fmt.Println("All clear!")

// FlushTimeout specifies a timeout value as well.
err := nc.FlushTimeout(1*time.Second)
if err != nil {
    fmt.Println("All clear!")
} else {
    fmt.Println("Flushed timed out!")
}

// Auto-unsubscribe after MAX_WANTED messages received
const MAX_WANTED = 10
sub, err := nc.Subscribe("foo")
sub.AutoUnsubscribe(MAX_WANTED)

// Multiple connections
nc1 := nats.Connect("nats://host1:4222")
nc2 := nats.Connect("nats://host2:4222")

nc1.Subscribe("foo", func(m *Msg) {
    fmt.Printf("Received a message: %s\n", string(m.Data))
})

nc2.Publish("foo", []byte("Hello World!"));

Clustered Usage

var servers = "nats://localhost:1222, nats://localhost:1223, nats://localhost:1224"

nc, err := nats.Connect(servers)

// Optionally set ReconnectWait and MaxReconnect attempts.
// This example means 10 seconds total per backend.
nc, err = nats.Connect(servers, nats.MaxReconnects(5), nats.ReconnectWait(2 * time.Second))

// You can also add some jitter for the reconnection.
// This call will add up to 500 milliseconds for non TLS connections and 2 seconds for TLS connections.
// If not specified, the library defaults to 100 milliseconds and 1 second, respectively.
nc, err = nats.Connect(servers, nats.ReconnectJitter(500*time.Millisecond, 2*time.Second))

// You can also specify a custom reconnect delay handler. If set, the library will invoke it when it has tried
// all URLs in its list. The value returned will be used as the total sleep time, so add your own jitter.
// The library will pass the number of times it went through the whole list.
nc, err = nats.Connect(servers, nats.CustomReconnectDelay(func(attempts int) time.Duration {
    return someBackoffFunction(attempts)
}))

// Optionally disable randomization of the server pool
nc, err = nats.Connect(servers, nats.DontRandomize())

// Setup callbacks to be notified on disconnects, reconnects and connection closed.
nc, err = nats.Connect(servers,
	nats.DisconnectErrHandler(func(nc *nats.Conn, err error) {
		fmt.Printf("Got disconnected! Reason: %q\n", err)
	}),
	nats.ReconnectHandler(func(nc *nats.Conn) {
		fmt.Printf("Got reconnected to %v!\n", nc.ConnectedUrl())
	}),
	nats.ClosedHandler(func(nc *nats.Conn) {
		fmt.Printf("Connection closed. Reason: %q\n", nc.LastError())
	})
)

// When connecting to a mesh of servers with auto-discovery capabilities,
// you may need to provide a username/password or token in order to connect
// to any server in that mesh when authentication is required.
// Instead of providing the credentials in the initial URL, you will use
// new option setters:
nc, err = nats.Connect("nats://localhost:4222", nats.UserInfo("foo", "bar"))

// For token based authentication:
nc, err = nats.Connect("nats://localhost:4222", nats.Token("S3cretT0ken"))

// You can even pass the two at the same time in case one of the server
// in the mesh requires token instead of user name and password.
nc, err = nats.Connect("nats://localhost:4222",
    nats.UserInfo("foo", "bar"),
    nats.Token("S3cretT0ken"))

// Note that if credentials are specified in the initial URLs, they take
// precedence on the credentials specified through the options.
// For instance, in the connect call below, the client library will use
// the user "my" and password "pwd" to connect to localhost:4222, however,
// it will use username "foo" and password "bar" when (re)connecting to
// a different server URL that it got as part of the auto-discovery.
nc, err = nats.Connect("nats://my:pwd@localhost:4222", nats.UserInfo("foo", "bar"))

Context support (+Go 1.7)

ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()

nc, err := nats.Connect(nats.DefaultURL)

// Request with context
msg, err := nc.RequestWithContext(ctx, "foo", []byte("bar"))

// Synchronous subscriber with context
sub, err := nc.SubscribeSync("foo")
msg, err := sub.NextMsgWithContext(ctx)

// Encoded Request with context
c, err := nats.NewEncodedConn(nc, nats.JSON_ENCODER)
type request struct {
	Message string `json:"message"`
}
type response struct {
	Code int `json:"code"`
}
req := &request{Message: "Hello"}
resp := &response{}
err := c.RequestWithContext(ctx, "foo", req, resp)

License

Unless otherwise noted, the NATS source files are distributed under the Apache Version 2.0 license found in the LICENSE file.

FOSSA Status

Owner
NATS - The Cloud Native Messaging System
NATS is a simple, secure and performant communications system for digital systems, services and devices.
NATS - The Cloud Native Messaging System
Comments
  • Cannot go get client

    Cannot go get client

    I have a project that is outside of the go src folder, I am running go 1.12.5 on windows amd64 (win10) This is my first attempt to use NATS, not a great start!

    Getting this error:

    go get github.com/nats-io/nats.go/ go: finding github.com/nats-io/nats.go v1.8.0 go: finding github.com/nats-io/nkeys v0.0.2 go: finding github.com/nats-io/nuid v1.0.1 go: finding golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9 CreateFile github.com/nats-io/nats.go: The system cannot find the path specified.

  • Not seeing v2.0.0 for nats-io/nats.go

    Not seeing v2.0.0 for nats-io/nats.go

    $ mkdir mymod
    $ cd mymod
    $ touch go.mod
    $ go get github.com/nats-io/nats.go@latest
    stat github.com/nats-io/nats.go: no such file or directory
    $ go get github.com/nats-io/nats.go/@latest
    $ cat go.mod
    module mymod
    
    go 1.12
    
    require (
    	github.com/nats-io/go-nats v1.7.2 // indirect
    	github.com/nats-io/nats.go v1.7.2 // indirect
    	github.com/nats-io/nkeys v0.0.2 // indirect
    	github.com/nats-io/nuid v1.0.1 // indirect
    )
    $ 
    

    Shouldn't it be v2.0.0?

  • Add TokenHandler option to connection options

    Add TokenHandler option to connection options

    This pull request adds TokenFunc to the Options struct. This adds a way to generate a new token every time a connectProto is built and allows the use of expiring tokens like JWTs when authenticating.

  • Mock NATS server implementation in order to be able to write unit tests

    Mock NATS server implementation in order to be able to write unit tests

    In order for consumers to be able to write unit tests for their subscription logic, they need a way to publish messages. Right now, this is not possible because a mock NATS server implementation has not been provided.

    This leaves the consumer with only one option: bring up an actual NATS server in your test suite. Which effectively means you are writing an integration test now. I want to avoid this as I want to test my service logic without bringing up external dependencies. Unit tests should be deterministic and not rely on any kind of network connectivity (e.g. bringing up NATS server locally would imply a port needs to be free on CI).

    The other option consumers have is to simply just unit test the message handler they pass in to their call to Subscribe(subj string, cb MsgHandler).

    What do you propose? Is there any workaround to this? Ideally, this package would provide some kind of mock NATS server somewhat similar to how opentracing go provides a mocktracer - https://github.com/opentracing/opentracing-go/tree/master/mocktracer so folks can write tests to ensure that their spans are being created as expected.

  • Subject interning

    Subject interning

    @derekcollison Please review. The price of this comparison near 2ns per operation but in case of plain subscriptions it reduces single allocation per operation and results in speedup. Looking forward for your comments. If somehow to know beforehand that subscription using wildcard then it's possible to make it no cost. So I suggest to merge this pull request first, than make some changes to subscription struct to contain isWildcard bool field and then switch to using it. so no need to compare strings just single if isWildcard and nothings else.

  • message consume too slow

    message consume too slow

    i created a stream in Retention=WorkQueuePolicy, and published 1 million messages. then i start to consume it.

    for {
      msgs, err := sub.Fetch(10000, nats.Context(ctx))
     for _, msg := range msgs {
    	msg.AckSync()
     }
    }
    

    the first batch fetched fast enough, after a few loops, Fetch( ) becomes too slow (> 10 seconds), and the whole batch ack time become too slow also.

  • Jetstream KV watcher does not watch after NATS server restart

    Jetstream KV watcher does not watch after NATS server restart

    KV watcher does not do its job after Nats server is restarted.

    nats.go version v1.17.0 nats server v2.9.1

    Steps or code to reproduce the issue:

    • Implement simple watch-all logic.
    • Run nats server and client. Make updates with keys in a bucket. See, updates are coming.
    • Restart nats server
    watcher, err := flowsKV.WatchAll(nats.Context(ctx))
    	if err != nil {
    		return err
    	}
    	defer watcher.Stop()
    	for {
    		select {
    		case update := <-watcher.Updates():
    			if update == nil {
    				break
    			}
    			
    		case <-ctx.Done():
    			return nil
    		}
    	}
    

    Expected result:

    After nats restart watcher backs to printing latest KV updates

    Actual result:

    Watcher gives no updates Error happens time to time nats: consumer not active on connection [101] for subscription on "$KV.bucket.>"


    js.Subscribe() without nats.OrderedConsumer() option behaves correctly, but this option is built-in into kv.Watch...

    Thanks.

  • Clean up logic around max handling to regress

    Clean up logic around max handling to regress

    I'm trying to test changes against my new Java client and believe that this is a little cleaner and fixes some edge race conditions. There are several more and not sure that these changes should be applied until a wider look at delivered/max logic is looked at here...

  • Unsubscribe does not allow consumption of already fetched messages

    Unsubscribe does not allow consumption of already fetched messages

    Perhaps there is a good reason for this, but it appears that Unsubscribe sets it's message channel to nil which is potentially a destructive action.

    Unless there is another way to consume messages that have already been fetched by the client. I would expect the channel to be closed to prevent future writes but to remain available for reads.

    s.unsubscribe()
    ...consume remaining messages in channel
    

    I am working on a PR that addresses this. I am curious though if this was intended behavior and if I am misusing it.

  • Golang client for NATS web socket

    Golang client for NATS web socket

    nats 2.2 supports binary web sockets which means I can use golang to build wasm based web apps to communicate with NATS server ?

    i was told via the nats.ws repo that the nats.go client may support compiling to wasm .

    Is this true ? It would be rather awesome

  • Return error if actual consumer configuration is different

    Return error if actual consumer configuration is different

    Feature Request

    When creating subscriptions I can pass extra options, e.g.:

    sub, err := js.PullSubscribe("TEST.*", "testing", nats.MaxDeliver(3))
    

    The consumer is created in NATS if it didn't exist yet:

    $ nats con info TEST testing
    Information for Consumer TEST > testing created 2021-08-17T11:37:10+02:00
    
    Configuration:
    
            Durable Name: testing
               Pull Mode: true
          Filter Subject: TEST.*
             Deliver All: true
              Ack Policy: Explicit
                Ack Wait: 30s
           Replay Policy: Instant
      Maximum Deliveries: 3
         Max Ack Pending: 20,000
       Max Waiting Pulls: 512
    
    State:
    ...
    

    If I then change the options, e.g.:

    sub, err := js.PullSubscribe("TEST.*", "testing", nats.MaxDeliver(5))
    

    Then the new value is silently ignored and the consumer still has Maximum Deliveries: 3. The options seems to be used only when creating a new consumer, but ignored otherwise (some of them at least).

    While it might not be feasible to transparently update the consumer, I would expect to get an error telling me that the requested options do not match the actual consumer configuration.

    Use Case:

    I can very easily imagine a situation where a developer changes the options (adds a new one, removes one, changes a value) thinking that it will work. For someone unfamiliar with NATS JS it's not obvious that some consumer object exists in NATS itself and that these options are not just client-side connection options. It's easy for the code to diverge from the actual configuration.

    Proposed Change:

    Compare the actual consumer configuration with the requested one an return an error if there's a mismatch.

    It seems that the existing configuration is already read (the info variable), so this shouldn't affect performance.

    Who Benefits From The Change(s)?

    Unwitting developers trying to change the consumer configuration.

    Alternative Approaches

    Update the consumer configuration to match the requested one.

  • add optional metadata to service

    add optional metadata to service

    This allows to add optional meta data to a service, for instance, in my case, the services are dispatched across multiple machines, on the edge.

    The ability to add meta data like this, and retrieve them in the PING, INFO... is very useful :

    	// ...
    	hostname, _ := os.Hostname()
    	externalIP := getmyip.ViaOpenDNS()
    
    	config := micro.Config{
    		Name:        "EchoService",
    		Version:     "1.0.0",
    		Description: "Send back what you receive",
    		Meta: map[string]interface{}{
    			"hostname":    hostname,
    			"external-ip": externalIP,
    		},
    		Endpoint: micro.Endpoint{
    			Subject: "echo",
    			Handler: echoHandler,
    		},
    		// ...
    	}
    	svc, err := micro.AddService(nc, config)
    	// ...
    
  • Unbound memory footprint growth with slow consumers

    Unbound memory footprint growth with slow consumers

    Defect

    • [x] Included nats.go version
    • [x] Included a [Minimal, Complete, and Verifiable example] (https://stackoverflow.com/help/mcve)

    Versions of nats.go and the nats-server if one was involved:

    nats.go @ 95a7e5090fda9532342375fe2954362905d43434 (today's main branch) nats-server @ 2.9.8 (probably not relevant)

    OS/Container environment:

    Not relevant

    Steps or code to reproduce the issue:

    • Create one or more NATS consumers that can't/won't keep up with actual traffic, e.g:
      • Sync subscription not being consumed
      • Async subscription where handler is slow
    • Publish messages faster than consumers consume them
    • Observe memory at the client grow until OOM

    This test (artificially) reproduces the situation in just a few seconds: https://github.com/mprimi/nats.go/commit/78cee182ea34ed864e2b67653a9b81fd2f1ecf1c

    Expected result:

    Client of slow consumers starts dropping messages. (This is NATS without JetStream, so message loss is acceptable)

    Actual result:

    Messages build up in the consumer client until the program starts trashing or gets OOM killed

    Comments

    The attached repro shows how a client can blow up in just a few seconds:

        [...]
        Published 1319 messages (12 MiB), runtime mem: 59 GiB
        Published 1379 messages (13 MiB), runtime mem: 62 GiB
        Published 1435 messages (14 MiB), runtime mem: 65 GiB
        Published 1551 messages (15 MiB), runtime mem: 70 GiB
        Published 1607 messages (15 MiB), runtime mem: 73 GiB
        Published 1663 messages (16 MiB), runtime mem: 76 GiB
       
    Process finished with the exit code 1 (OOM panic)
    

    The test is artificial, probably no real-world application behaves this way (e.g. thousands of subscriptions to the same subject, none being consumed).

    However this behavior is generalizable, this is the real takeaway:

    If an application is consuming subscriptions at a rate slower than messages are being published, then the client memory usage will keep growing without bounds. Eventually this application will run out of memory and crash (it may take hours/days/weeks instead of seconds).

    Suggested change

    The client should cap the amount of memory used to store unconsumed messages. Once the limit is reached, the client should start dropping messages.

    Optimizations

    This experiment also suggests a couple possible optimizations.

    Take the following situation:

    • Publisher is publishing the same 10KiB message 1000 times with subject 's'
    • Subscriber has 5000 subscriptions matching 's'

    As of now, the subscriber client will use an estimate ~50GiB (10KiB * 1000 messages * 5000 subscriptions)

    1. If the message content was de-duped internally and shared across subscriptions, then the memory footprint could be just 10MiB (10KiB * 1000 messages)

    2. If the message content was further de-duped because the client notices it's the same message being published over and over, then the footprint could be just 10KiB

    (I'm not suggesting semantical de-duping -- just internal memory storage de-duping, not visible outside the client)

    These optimizations may not be very beneficial in 'real world' scenario, since a client may not often be receiving tons of duplicate messages in the same subscription or across subscriptions.

  • Dependency loop with nats-server

    Dependency loop with nats-server

    Defect

    Make sure that these boxes are checked before submitting your issue -- thank you!

    • [x] Included nats.go version
    • [x] Included a [Minimal, Complete, and Verifiable example] (https://stackoverflow.com/help/mcve)

    Versions of nats.go and the nats-server if one was involved:

    nats.go version: 1.20.0 nats-server version: 2.9.8

    OS/Container environment:

    Debian sid

    Steps or code to reproduce the issue:

    I am working on updating some of the various nats-io packages in Debian, and observed that there is a dependency loop between nats.go and nats-server. While the nats-server dependency is only needed by tests in nats.go (see the go_test.mod file), that still forms a dependency loop. For the time being to break the loop, the nats.go tests are disabled in the Debian package, but that's clearly not an optimal solution.

Nats-subject-profiler - NATS Subject Profiler With Golang

NATS Subject Profiler Example Connect it to the demo NATS server. nats-subject-p

Feb 7, 2022
Simple-messaging - Brokerless messaging. Pub/Sub. Producer/Consumer. Pure Go. No C.

Simple Messaging Simple messaging for pub/sub and producer/consumer. Pure Go! Usage Request-Response Producer: consumerAddr, err := net.ResolveTCPAddr

Jan 20, 2022
Queue with NATS Jetstream to remove all the erlangs from cloud

Saf in Persian means Queue. One of the problems, that we face on projects with queues is deploying RabbitMQ on the cloud which brings us many challenges for CPU load, etc. I want to see how NATS with Jetstream can work as the queue to replace RabbitMQ.

Dec 15, 2022
stratus is a cross-cloud identity broker that allows workloads with an identity issued by one cloud provider to exchange this identity for a workload identity issued by another cloud provider.
stratus is a cross-cloud identity broker that allows workloads with an identity issued by one cloud provider to exchange this identity for a workload identity issued by another cloud provider.

stratus stratus is a cross-cloud identity broker that allows workloads with an identity issued by one cloud provider to exchange this identity for a w

Dec 26, 2021
πŸ’¨ A real time messaging system to build a scalable in-app notifications, multiplayer games, chat apps in web and mobile apps.
πŸ’¨ A real time messaging system to build a scalable in-app notifications, multiplayer games, chat apps in web and mobile apps.

Beaver A Real Time Messaging Server. Beaver is a real-time messaging server. With beaver you can easily build scalable in-app notifications, realtime

Jan 1, 2023
Go client library SDK for Ably realtime messaging service

Ably Go A Go client library for www.ably.io, the realtime messaging service. Installation ~ $ go get -u github.com/ably/ably-go/ably Feature support T

Dec 2, 2022
NATS example to store and retrieve large file assets from JetStream.

njs-xfer njs-xfer is a sample application that demonstrates the ability to use NATS and JetStream to store and retrieve large file assets. This sample

Dec 26, 2022
NATS Key-Value Store based Leader Election

What? A Leader Election system that uses keys in a NATS Key-Value Store to perform leader election. How? NATS KV Buckets have a TTL, creating a bucket

Dec 27, 2022
ΠœΠΎΡΡ‚ ΠΌΠ΅ΠΆΠ΄Ρƒ NATS streaming ΠΈ MQ Series

ΠœΠΎΡΡ‚ ΠΌΠ΅ΠΆΠ΄Ρƒ NATS streaming ΠΈ MQ Series ΠžΡ€ΠΈΠ³ΠΈΠ½Π°Π»ΡŒΠ½Ρ‹ΠΉ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ https://github.com/nats-io/nats-mq NATS-MQ Bridge This project implements a simple, but

Nov 26, 2021
Basic kick the tires on NATS Key-Value API (Go)

nats-kv-101 Basic kick the tires on NATS Key-Value API (Go) Usage # Get ./mybucket -s "nats://vbox1.tinghus.net" -creds "/home/todd/lab/nats-cluster1/

Feb 15, 2022
A basic pub-sub project using NATS

NATS Simple Pub-Sub Mechanism This is a basic pub-sub project using NATS. There is one publisher who publishes a "Hello World" message to a subject ca

Dec 13, 2021
Vigia-go-nats - Program for processing camera metadata

VIGIA MIGRAR O HOUSEKEEPER PARA O PYTHON Programa para processamento de metadado

Jan 10, 2022
Kafka implemented in Golang with built-in coordination (No ZooKeeper, single binary install, Cloud Native)

Jocko Distributed commit log service in Go that is wire compatible with Kafka. Created by @travisjeffery, continued by nash. Goals: Protocol compatibl

Aug 9, 2021
Tool for collect statistics from AMQP (RabbitMQ) broker. Good for cloud native service calculation.

amqp-statisticator Tool for collect statistics around your AMQP broker. For example RabbitMQ expose a lot information trought the management API, but

Dec 13, 2021
websocket based messaging server written in golang

Guble Messaging Server Guble is a simple user-facing messaging and data replication server written in Go. Overview Guble is in an early state (release

Oct 19, 2022
Golang Restful API Messaging using GORM ORM (MySQL) Gorilla Mux

Golang Restful API Messaging using GORM ORM (MySQL) Gorilla Mux Getting Started Folder Structure This is my folder structure under my $GOPATH or $HOME

Dec 14, 2021
Scalable real-time messaging server in language-agnostic way
Scalable real-time messaging server in language-agnostic way

Centrifugo is a scalable real-time messaging server in language-agnostic way. Centrifugo works in conjunction with application backend written in any

Jan 2, 2023
Abstraction layer for simple rabbitMQ connection, messaging and administration
Abstraction layer for simple rabbitMQ connection, messaging and administration

Jazz Abstraction layer for quick and simple rabbitMQ connection, messaging and administration. Inspired by Jazz Jackrabbit and his eternal hatred towa

Dec 12, 2022
A dead simple Go library for sending notifications to various messaging services.
A dead simple Go library for sending notifications to various messaging services.

A dead simple Go library for sending notifications to various messaging services. About Notify arose from my own need for one of my api server running

Jan 7, 2023