mirror of
https://gitlab.com/djdietrick/docs
synced 2026-05-03 01:30:55 -04:00
98 lines
2.1 KiB
Markdown
98 lines
2.1 KiB
Markdown
# RPC
|
|
|
|
RPC stands for Remote Procedure Calls, and allows for external Go microservices to call functions in our application directly.
|
|
|
|
## Listener
|
|
|
|
To do this, you need to define a RPCServer dummy type, and payload to receive, and a function that gets a pointer to a response string and returns an error.
|
|
|
|
```go
|
|
type RPCServer struct{}
|
|
|
|
type RPCPayload struct {
|
|
Name string
|
|
Data string
|
|
}
|
|
|
|
func (r *RPCServer) LogInfo(payload RPCPayload, resp *string) error {
|
|
collection := client.Database("logs").Collection("logs")
|
|
_, err := collection.InsertOne(context.TODO(), data.LogEntry{
|
|
Name: payload.Name,
|
|
Data: payload.Data,
|
|
})
|
|
if err != nil {
|
|
log.Println("error writing to mongo ", err)
|
|
return err
|
|
}
|
|
*resp = "processed payload via RPC: " + payload.Name
|
|
|
|
return nil
|
|
}
|
|
|
|
```
|
|
|
|
To instantiate the RPCServer, use the below syntax in your main application file. Basically you define a function that creates the connection and listens on a port. Then, you register your RPC handler type and serve the RPC server.
|
|
|
|
```go
|
|
func (app *Config) rpcListen() error {
|
|
log.Println("Starting RPC server on port " + RPC_PORT)
|
|
listen, err := net.Listen("tcp", fmt.Sprintf("0.0.0.0:%s", RPC_PORT))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer listen.Close()
|
|
|
|
for {
|
|
rpcConn, err := listen.Accept()
|
|
if err != nil {
|
|
log.Println("Error accepting connection: ", err)
|
|
continue
|
|
}
|
|
go rpc.ServeConn(rpcConn)
|
|
}
|
|
}
|
|
|
|
// in function where you start your app...
|
|
err = rpc.Register(new(RPCServer))
|
|
go app.rpcListen()
|
|
```
|
|
|
|
## Sender
|
|
|
|
To send messages via RPC, you need to create a type for the payload that exactly matches that of the receiver.
|
|
|
|
```go
|
|
type RPCPayload struct {
|
|
Name string
|
|
Data string
|
|
}
|
|
|
|
func (app *Config) logItemViaRPC(r http.ResponseWriter, l LogPayload) {
|
|
client, err := rpc.Dial("tcp", "logger:5001")
|
|
if err != nil {
|
|
app.errorJSON(r, err)
|
|
return
|
|
}
|
|
|
|
payload := RPCPayload{
|
|
Name: l.Name,
|
|
Data: l.Data,
|
|
}
|
|
|
|
var resp string
|
|
|
|
err = client.Call("RPCServer.LogInfo", payload, &resp)
|
|
if err != nil {
|
|
app.errorJSON(r, err)
|
|
return
|
|
}
|
|
|
|
returnPayload := jsonResponse{
|
|
Error: false,
|
|
Message: resp,
|
|
}
|
|
|
|
app.writeJSON(r, http.StatusAccepted, returnPayload)
|
|
}
|
|
```
|