The package rpcmq implements an RPC protocol over AMQP.
go get github.com/jroimartin/rpcmq
godoc github.com/jroimartin/rpcmq
The following snippets show how easy is to implement both an RPC client and server using rpcmq. In this example the server registers a new method called "toUpper" that takes an string and convert it to uppercase. On the other hand, the RPC client will invoke this method remotely. Then, after 10 seconds, the client and the server will shutdown.
server.go
package main
import (
"log"
"strings"
"time"
"github.com/jroimartin/rpcmq"
)
func main() {
s := rpcmq.NewServer("amqp://amqp_broker:5672",
"rpc-queue", "rpc-exchange", "direct")
if err := s.Register("toUpper", toUpper); err != nil {
log.Fatalf("Register: %v", err)
}
if err := s.Init(); err != nil {
log.Fatalf("Init: %v", err)
}
defer s.Shutdown()
time.Sleep(1 * time.Minute)
}
func toUpper(id string, data []byte) ([]byte, error) {
log.Printf("Received (%v): toUpper(%v)\n", id, string(data))
return []byte(strings.ToUpper(string(data))), nil
}
client.go
package main
import (
"log"
"time"
"github.com/jroimartin/rpcmq"
)
func main() {
c := rpcmq.NewClient("amqp://amqp_broker:5672",
"rpc-queue", "rpc-client", "rpc-exchange", "direct")
if err := c.Init(); err != nil {
log.Fatalf("Init: %v", err)
}
defer c.Shutdown()
go func() {
for {
data := []byte("Hello gophers!")
uuid, err := c.Call("toUpper", data, 0)
if err != nil {
log.Println("Call:", err)
}
log.Printf("Sent: toUpper(%v) (%v)\n", string(data), uuid)
time.Sleep(500 * time.Millisecond)
}
}()
go func() {
for r := range c.Results() {
if r.Err != "" {
log.Printf("Received error: %v (%v)", r.Err, r.UUID)
continue
}
log.Printf("Received: %v (%v)\n", string(r.Data), r.UUID)
}
}()
time.Sleep(1 * time.Minute)
}
This code will generate the following output: