srpc/server.go

179 lines
3.4 KiB
Go
Raw Normal View History

2019-10-22 01:32:56 +02:00
package srpc
import (
2019-11-05 18:21:41 +01:00
"bytes"
"errors"
2019-11-05 18:21:41 +01:00
"fmt"
2019-11-08 02:14:36 +01:00
"log"
"net"
2019-11-05 18:21:41 +01:00
"reflect"
2019-10-22 01:32:56 +02:00
"sync"
)
2019-10-22 15:36:14 +02:00
type argumentType uint8
type responseStatus uint8
2019-10-22 01:32:56 +02:00
const (
2019-10-22 15:36:14 +02:00
OK responseStatus = 0
ERR responseStatus = 1
2019-10-22 01:32:56 +02:00
)
var RESPONSE_HEADER_SIZE = int32(9)
type responseHeader struct {
size int64
2019-10-22 15:36:14 +02:00
status responseStatus
2019-10-22 01:32:56 +02:00
}
2019-11-05 18:21:41 +01:00
type parseInputsFunc func(in []byte) (ret []reflect.Value)
type parseOutputsFunc func(in []reflect.Value) (ret []byte)
2019-11-05 18:21:41 +01:00
type service struct {
f reflect.Value
fin parseInputsFunc
fout parseOutputsFunc
2019-11-05 18:21:41 +01:00
}
2019-10-22 01:32:56 +02:00
type Server struct {
2020-02-10 02:53:05 +01:00
ed IEncoderDecoder
2019-10-22 01:32:56 +02:00
serviceMap sync.Map
}
2019-11-08 02:14:36 +01:00
func (server *Server) ServeConn(conn net.Conn) {
var fs service
2020-02-10 02:53:05 +01:00
dec := server.ed.NewDecoder(conn)
2019-11-08 02:14:36 +01:00
2020-02-10 02:53:05 +01:00
var req request
dec.Decode(&req)
fmt.Println(req)
2019-11-08 02:14:36 +01:00
2020-02-10 02:53:05 +01:00
if fsRaw, ok := server.serviceMap.Load(req.FuncName); !ok {
log.Printf("srpc: Call to unknown method: '%s'", req.FuncName)
2019-11-08 02:14:36 +01:00
return
} else {
fs = fsRaw.(service)
}
2020-02-10 02:53:05 +01:00
inputs := fs.fin(req.Payload)
2019-11-08 02:14:36 +01:00
outputs := fs.f.Call(inputs)
log.Println(outputs)
2020-02-10 02:53:05 +01:00
respData := fs.fout(outputs)
respSize := int64(len(respData))
enc := server.ed.NewEncoder(conn)
enc.Encode(respSize)
enc.Encode(respData)
2019-10-22 01:32:56 +02:00
}
2019-11-08 02:14:36 +01:00
func (server *Server) Accept(ln net.Listener) {
for {
conn, err := ln.Accept()
if err != nil {
log.Printf("srpc: accept: %s", err.Error())
return
}
go server.ServeConn(conn)
}
}
2019-11-05 18:21:41 +01:00
func (server *Server) RegisterName(name string, rcvr interface{}) (err error) {
if _, ok := server.serviceMap.Load(name); ok {
return errors.New("srpc: Function with name '" + name + "' already registerd")
}
2019-11-05 18:21:41 +01:00
ft := reflect.TypeOf(rcvr)
fv := reflect.ValueOf(rcvr)
nIn := ft.NumIn()
fs := service{}
fs.fin = func(in []byte) (ret []reflect.Value) {
2019-11-05 18:21:41 +01:00
var b bytes.Buffer
if _, err = b.Write(in); err != nil {
return nil
}
2020-02-10 02:53:05 +01:00
decoder := server.ed.NewDecoder(&b)
2019-11-05 18:21:41 +01:00
ret = make([]reflect.Value, nIn)
for i := 0; i < nIn; i++ {
in := reflect.New(ft.In(i))
if err = decoder.Decode(in.Interface()); err != nil {
fmt.Println(err)
return nil
}
ret[i] = reflect.Indirect(in)
}
return ret
}
fs.fout = func(in []reflect.Value) (ret []byte) {
var b bytes.Buffer
2020-02-10 02:53:05 +01:00
encoder := server.ed.NewEncoder(&b)
for _, v := range in {
if v.Type() == reflect.TypeOf((*error)(nil)).Elem() {
if v.IsNil() {
if err := encoder.Encode(string("")); err != nil {
fmt.Println(err)
return nil
}
} else {
if err := encoder.Encode(v.Interface().(error).Error()); err != nil {
fmt.Println(err)
return nil
}
}
} else {
if err := encoder.Encode(v.Interface()); err != nil {
fmt.Println(err)
return nil
}
}
}
return b.Bytes()
}
2019-11-05 18:21:41 +01:00
fs.f = fv
server.serviceMap.Store(name, fs)
return nil
}
2019-11-08 02:14:36 +01:00
func (server *Server) CallName(name string, args ...interface{}) (ret []byte, err error) {
var b bytes.Buffer
2019-11-08 02:14:36 +01:00
var fs service
2020-02-10 02:53:05 +01:00
encoder := server.ed.NewEncoder(&b)
2019-11-08 02:14:36 +01:00
if fsRaw, ok := server.serviceMap.Load(name); !ok {
return nil, errors.New("srpc: Call to unknown method: '" + name + "'")
} else {
fs = fsRaw.(service)
}
2019-11-05 18:21:41 +01:00
for _, a := range args {
if err := encoder.Encode(a); err != nil {
2019-11-08 02:14:36 +01:00
return nil, errors.New("srpc: Error: '" + err.Error() + "'")
}
}
2019-11-08 02:14:36 +01:00
inputs := fs.fin(b.Bytes())
outputs := fs.f.Call(inputs)
return fs.fout(outputs), nil
2019-11-05 18:21:41 +01:00
}
2019-11-08 02:14:36 +01:00
2020-02-10 02:53:05 +01:00
func NewServer(ed IEncoderDecoder) *Server {
ret := &Server{}
ret.ed = ed
return ret
}
func NewDefaultServer() *Server {
ret := NewServer(NewEncoderDecoder())
return ret
2019-11-08 02:14:36 +01:00
}
2020-02-10 02:53:05 +01:00
var DefaultServer = NewDefaultServer()