gobot.io/x/gobot@v1.16.0/platforms/nats/nats_adaptor.go (about) 1 package nats 2 3 import ( 4 "net/url" 5 "strings" 6 7 "github.com/nats-io/nats.go" 8 "gobot.io/x/gobot" 9 ) 10 11 // Adaptor is a configuration struct for interacting with a NATS server. 12 // Name is a logical name for the adaptor/nats server connection. 13 // Host is in the form "localhost:4222" which is the hostname/ip and port of the nats server. 14 // ClientID is a unique identifier integer that specifies the identity of the client. 15 type Adaptor struct { 16 name string 17 Host string 18 clientID int 19 username string 20 password string 21 client *nats.Conn 22 connect func() (*nats.Conn, error) 23 } 24 25 // Message is a message received from the server. 26 type Message *nats.Msg 27 28 // NewAdaptor populates a new NATS Adaptor. 29 func NewAdaptor(host string, clientID int, options ...nats.Option) *Adaptor { 30 hosts, err := processHostString(host) 31 32 return &Adaptor{ 33 name: gobot.DefaultName("NATS"), 34 Host: hosts, 35 clientID: clientID, 36 connect: func() (*nats.Conn, error) { 37 if err != nil { 38 return nil, err 39 } 40 return nats.Connect(hosts, options...) 41 }, 42 } 43 } 44 45 // NewAdaptorWithAuth populates a NATS Adaptor including username and password. 46 func NewAdaptorWithAuth(host string, clientID int, username string, password string, options ...nats.Option) *Adaptor { 47 hosts, err := processHostString(host) 48 49 return &Adaptor{ 50 Host: hosts, 51 clientID: clientID, 52 username: username, 53 password: password, 54 connect: func() (*nats.Conn, error) { 55 if err != nil { 56 return nil, err 57 } 58 return nats.Connect(hosts, append(options, nats.UserInfo(username, password))...) 59 }, 60 } 61 } 62 63 func processHostString(host string) (string, error) { 64 urls := strings.Split(host, ",") 65 for i, s := range urls { 66 s = strings.TrimSpace(s) 67 if !strings.HasPrefix(s, "tls://") && !strings.HasPrefix(s, "nats://") { 68 s = "nats://" + s 69 } 70 71 u, err := url.Parse(s) 72 if err != nil { 73 return "", err 74 } 75 76 urls[i] = u.String() 77 } 78 79 return strings.Join(urls, ","), nil 80 } 81 82 // Name returns the logical client name. 83 func (a *Adaptor) Name() string { return a.name } 84 85 // SetName sets the logical client name. 86 func (a *Adaptor) SetName(n string) { a.name = n } 87 88 // Connect makes a connection to the Nats server. 89 func (a *Adaptor) Connect() (err error) { 90 a.client, err = a.connect() 91 return 92 } 93 94 // Disconnect from the nats server. 95 func (a *Adaptor) Disconnect() (err error) { 96 if a.client != nil { 97 a.client.Close() 98 } 99 return 100 } 101 102 // Finalize is simply a helper method for the disconnect. 103 func (a *Adaptor) Finalize() (err error) { 104 a.Disconnect() 105 return 106 } 107 108 // Publish sends a message with the particular topic to the nats server. 109 func (a *Adaptor) Publish(topic string, message []byte) bool { 110 if a.client == nil { 111 return false 112 } 113 a.client.Publish(topic, message) 114 return true 115 } 116 117 // On is an event-handler style subscriber to a particular topic (named event). 118 // Supply a handler function to use the bytes returned by the server. 119 func (a *Adaptor) On(event string, f func(msg Message)) bool { 120 if a.client == nil { 121 return false 122 } 123 a.client.Subscribe(event, func(msg *nats.Msg) { 124 f(msg) 125 }) 126 127 return true 128 }