2019-10-22 01:32:56 +02:00
|
|
|
package srpc
|
|
|
|
|
|
|
|
import (
|
2019-11-05 18:21:41 +01:00
|
|
|
"bytes"
|
2019-11-06 01:16:23 +01:00
|
|
|
"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
|
|
|
"olznet.de/ssob"
|
|
|
|
"reflect"
|
2019-10-22 01:32:56 +02:00
|
|
|
"sync"
|
|
|
|
)
|
|
|
|
|
2019-10-22 15:36:14 +02:00
|
|
|
type argumentType uint8
|
|
|
|
|
2019-10-22 01:32:56 +02:00
|
|
|
const (
|
2019-10-22 15:36:14 +02:00
|
|
|
AIN argumentType = 0
|
|
|
|
AOUT argumentType = 1
|
|
|
|
AINOUT argumentType = 2
|
2019-10-22 01:32:56 +02:00
|
|
|
)
|
|
|
|
|
2019-10-22 15:36:14 +02:00
|
|
|
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)
|
2019-11-06 01:16:23 +01:00
|
|
|
type parseOutputsFunc func(in []reflect.Value) (ret []byte)
|
2019-11-05 18:21:41 +01:00
|
|
|
|
|
|
|
type service struct {
|
2019-11-06 01:16:23 +01:00
|
|
|
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 {
|
|
|
|
serviceMap sync.Map
|
|
|
|
}
|
|
|
|
|
2019-11-08 02:14:36 +01:00
|
|
|
func (server *Server) ServeConn(conn net.Conn) {
|
|
|
|
var b bytes.Buffer
|
|
|
|
var fs service
|
|
|
|
size := int64(0)
|
|
|
|
name := string("")
|
|
|
|
|
|
|
|
dec := ssob.NewDecoder(&b)
|
|
|
|
|
|
|
|
sizeb := make([]byte, 12)
|
|
|
|
conn.Read(sizeb)
|
|
|
|
|
|
|
|
b.Write(sizeb)
|
|
|
|
dec.Decode(&size)
|
|
|
|
log.Println(size)
|
|
|
|
|
|
|
|
payload := make([]byte, size)
|
|
|
|
conn.Read(payload)
|
|
|
|
b.Reset()
|
|
|
|
b.Write(payload)
|
|
|
|
log.Println(b.Bytes())
|
|
|
|
|
|
|
|
dec.Decode(&name)
|
|
|
|
log.Println(name)
|
|
|
|
|
|
|
|
if fsRaw, ok := server.serviceMap.Load(name); !ok {
|
|
|
|
log.Printf("srpc: Call to unknown method: '%s'", name)
|
|
|
|
return
|
|
|
|
} else {
|
|
|
|
fs = fsRaw.(service)
|
|
|
|
}
|
|
|
|
|
|
|
|
inputs := fs.fin(b.Bytes())
|
|
|
|
outputs := fs.f.Call(inputs)
|
|
|
|
log.Println(outputs)
|
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) {
|
2019-11-06 01:16:23 +01:00
|
|
|
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()
|
|
|
|
//nOut := ft.NumOut()
|
|
|
|
|
|
|
|
fs := service{}
|
|
|
|
|
2019-11-06 01:16:23 +01:00
|
|
|
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
|
|
|
|
}
|
|
|
|
decoder := ssob.NewDecoder(&b)
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2019-11-06 01:16:23 +01:00
|
|
|
fs.fout = func(in []reflect.Value) (ret []byte) {
|
|
|
|
var b bytes.Buffer
|
|
|
|
encoder := ssob.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) {
|
2019-11-06 01:16:23 +01:00
|
|
|
var b bytes.Buffer
|
2019-11-08 02:14:36 +01:00
|
|
|
var fs service
|
2019-11-06 01:16:23 +01:00
|
|
|
encoder := ssob.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
|
|
|
|
2019-11-06 01:16:23 +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-06 01:16:23 +01:00
|
|
|
}
|
|
|
|
}
|
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
|
|
|
|
|
|
|
func NewServer() *Server {
|
|
|
|
return &Server{}
|
|
|
|
}
|
|
|
|
|
|
|
|
var DefaultServer = NewServer()
|