protobuf-NATS-queue-groups example
Using NATS (queue groups) as a pipe to send protobuf messages.
This is a model for one-to-one communication.
These are my 6 main example of using protobuf,
Table of contents,
Documentation and reference,
GitHub Webpage
OVERVIEW OF NATS ARCHITECTURES
We have 3 examples using NATS as a pipe. This diagram may help,
START YOUR NATS SERVER
Using NATS as a pipe. First, lets start your NATS server,
nats-server -v
nats-server -DV -p 4222 -a 127.0.0.1
Where -DV is both debug and trace log.
GET NATS GO CLIENT LIBRARY
You must have this library to use go,
go get -v -u github.com/nats-io/nats.go/
PROTOCOL .proto BUFFER FILE
Lets use the same protobuf file messages.proto
in all four examples,
message Person {
string name = 1;
int32 age = 2;
string email = 3;
string phone = 4;
uint32 count = 5;
}
Compile the protocol buffer file to get the wrappers,
protoc --go_out=. messages.proto
Place wrapper file messages.pb.go
in both the client and server directories.
RUN
This example will publish a message every second to NATS and
whoever is subscribed will get the message. This is referred to as
one-to-one.
Using queue subscribers will balance message delivery across a group
of subscribers which can be used to provide application fault tolerance
and scale workload processing.
In separate windows run,
cd client
go run client.go messages.pb.go
cd server
go run server.go messages.pb.go
You can run as many servers as you want, each
will get a unique message.
FLOW - HOW DOES IT WORK
First you need to connect to the NATS server in go,
nc, err := nats.Connect("nats://127.0.0.1:4222")
defer nc.Close()
Lets look at the entire flow data -> marshal -> snd -> rcv -> unmarshal -> data
.
DATA
sndPerson := &Person{
Name: "Jeff",
Age: 20,
Email: "blah@blah.com",
Phone: "555-555-5555",
Count: count,
}
MARSHAL
msg, err := proto.Marshal(sndPerson)
SEND (PUBLISH)
nc.Publish("foo", msg)
RECEIVE (SUBSCRIBE)
To create a queue subscription, subscribers register a queue name.
All subscribers with the same queue name form the queue group.
// RECEIVE
nc.QueueSubscribe("foo", "jeffsQueue", func(msg *nats.Msg) {
// UNMARSHAL -> DATA
<SEE BELOW>
})
UNMARSHAL -> DATA
rcvPerson := &Person{}
err = proto.Unmarshal(msg.Data, rcvPerson)
HIGH-LEVEL ILLUSTRATION
This illustration may help show what we did,