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  }