package srpc import ( "bytes" "errors" "fmt" "log" "net" "olznet.de/ssob" "reflect" "sync" ) type argumentType uint8 const ( AIN argumentType = 0 AOUT argumentType = 1 AINOUT argumentType = 2 ) type responseStatus uint8 const ( OK responseStatus = 0 ERR responseStatus = 1 ) var RESPONSE_HEADER_SIZE = int32(9) type responseHeader struct { size int64 status responseStatus } type parseInputsFunc func(in []byte) (ret []reflect.Value) type parseOutputsFunc func(in []reflect.Value) (ret []byte) type service struct { f reflect.Value fin parseInputsFunc fout parseOutputsFunc } type Server struct { serviceMap sync.Map } 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) } 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) } } 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") } ft := reflect.TypeOf(rcvr) fv := reflect.ValueOf(rcvr) nIn := ft.NumIn() //nOut := ft.NumOut() fs := service{} fs.fin = func(in []byte) (ret []reflect.Value) { 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 } 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() } fs.f = fv server.serviceMap.Store(name, fs) return nil } func (server *Server) CallName(name string, args ...interface{}) (ret []byte, err error) { var b bytes.Buffer var fs service encoder := ssob.NewEncoder(&b) if fsRaw, ok := server.serviceMap.Load(name); !ok { return nil, errors.New("srpc: Call to unknown method: '" + name + "'") } else { fs = fsRaw.(service) } for _, a := range args { if err := encoder.Encode(a); err != nil { return nil, errors.New("srpc: Error: '" + err.Error() + "'") } } inputs := fs.fin(b.Bytes()) outputs := fs.f.Call(inputs) return fs.fout(outputs), nil } func NewServer() *Server { return &Server{} } var DefaultServer = NewServer()