srpc/client.go

103 lines
1.9 KiB
Go
Raw Normal View History

2019-10-22 01:32:56 +02:00
package srpc
2020-02-10 02:53:05 +01:00
import (
"bytes"
"errors"
2020-02-18 03:03:02 +01:00
"fmt"
2020-02-10 02:53:05 +01:00
"io"
"net"
2020-02-18 03:03:02 +01:00
"sync"
"time"
2020-02-10 02:53:05 +01:00
)
type Client struct {
2020-02-18 03:03:02 +01:00
sync.RWMutex
ed IEncoderDecoder
conn IRPCConn
running bool
2020-02-10 02:53:05 +01:00
}
func (client *Client) Call(funcName string, args ...interface{}) (ret []byte, err error) {
2020-02-10 02:53:05 +01:00
var b bytes.Buffer
enc := client.ed.NewEncoder(&b)
for _, a := range args {
enc.Encode(a)
}
payload := b.Bytes()
req := RPCRequest{funcName, payload}
2020-02-10 02:53:05 +01:00
2020-02-18 03:03:02 +01:00
client.RLock()
defer client.RUnlock()
if err = client.conn.Send(&req); err != nil {
return nil, err
}
2020-02-10 02:53:05 +01:00
2020-02-18 03:03:02 +01:00
var call *RPCCall
if call, err = client.conn.Receive(); err != nil {
return nil, err
}
2020-02-10 02:53:05 +01:00
2020-02-18 03:03:02 +01:00
var response *RPCResponse
var ok bool
if response, ok = call.Payload.(*RPCResponse); !ok {
return nil, errors.New("srpc - Expected response")
}
if response.Status != RPCOK {
err = errors.New("srpc - Response contained error: '" + response.Error + "'")
2020-02-14 01:51:30 +01:00
}
return response.Payload, err
2020-02-10 02:53:05 +01:00
}
2020-02-18 03:03:02 +01:00
func (client *Client) Close() {
client.Lock()
defer client.Unlock()
client.conn.Send(new(RPCClose))
client.running = false
}
2020-02-10 02:53:05 +01:00
func (client *Client) NewDecoder(r io.Reader) IDecoder {
return client.ed.NewDecoder(r)
}
func NewClient(conn net.Conn) *Client {
2020-02-18 03:03:02 +01:00
ret := &Client{sync.RWMutex{}, NewEncoderDecoder(), NewNetConn(conn, NewEncoderDecoder()), true}
go func() {
for {
fmt.Println("heartbeat")
ret.Lock()
if ret.running == false {
ret.Unlock()
return
}
ret.conn.Send(new(RPCHeartbeat))
if _, err := ret.conn.Receive(); err != nil {
ret.conn.Send(new(RPCClose))
ret.Unlock()
return
}
fmt.Println("got heartbeat")
ret.Unlock()
time.Sleep(15 * time.Second)
}
}()
return ret
2019-10-22 01:32:56 +02:00
}
2020-02-19 01:36:18 +01:00
type DialFunc func(addr string) (conn io.ReadWriteCloser, err error)
func unixDial(addr string) (conn io.ReadWriteCloser, err error) {
if conn, err = net.Dial("unix", addr); err != nil {
return nil, err
}
return conn, nil
}