From 8c63c7fd9688918764c1549bdba83996f2349c85 Mon Sep 17 00:00:00 2001 From: qydysky Date: Sat, 1 Jul 2023 16:02:18 +0800 Subject: [PATCH] add --- rpc/Rpc.go | 81 +++++++++++++++++++++++++++++++++++++++++++++++++ rpc/Rpc_test.go | 60 ++++++++++++++++++++++++++++++++++++ 2 files changed, 141 insertions(+) create mode 100644 rpc/Rpc.go create mode 100644 rpc/Rpc_test.go diff --git a/rpc/Rpc.go b/rpc/Rpc.go new file mode 100644 index 0000000..a251d23 --- /dev/null +++ b/rpc/Rpc.go @@ -0,0 +1,81 @@ +package part + +import ( + "net/http" + "net/rpc" + + web "github.com/qydysky/part/web" +) + +type Gob struct { + Key string + Data any +} + +type DealGob struct { + deal func(*Gob, *Gob) error +} + +func newDealGob(deal func(i *Gob, o *Gob) error) *DealGob { + return &DealGob{deal} +} + +func (t *DealGob) Deal(i *Gob, o *Gob) error { + return t.deal(i, o) +} + +type Pob struct { + Host string `json:"host"` + Path string `json:"path"` + s *rpc.Server + c *rpc.Client +} + +func (t *Pob) Server(deal func(i, o *Gob) error) (shutdown func(), err error) { + var path web.WebPath + webSync := web.NewSyncMap(&http.Server{ + Addr: t.Host, + }, &path) + shutdown = webSync.Shutdown + + t.s = rpc.NewServer() + if e := t.s.Register(newDealGob(deal)); e != nil { + err = e + return + } + + path.Store(t.Path, func(w http.ResponseWriter, r *http.Request) { + t.s.ServeHTTP(w, r) + }) + return +} + +func (t *Pob) Client() (pobClient *PobClient, err error) { + t.c, err = rpc.DialHTTPPath("tcp", t.Host, t.Path) + pobClient = &PobClient{t.c} + return +} + +type PobClient struct { + c *rpc.Client +} + +func (t *PobClient) Close() { + t.c.Close() +} + +func (t *PobClient) CallIO(i, o *Gob) (err error) { + return t.c.Call("DealGob.Deal", i, o) +} + +func (t *PobClient) GoIO(i, o *Gob, done chan *rpc.Call) *rpc.Call { + return t.c.Go("DealGob.Deal", i, o, done) +} + +func (t *PobClient) Call(g *Gob) (err error) { + return t.c.Call("DealGob.Deal", g, g) +} + +func (t *PobClient) Go(g *Gob, done chan *rpc.Call) *rpc.Call { + return t.c.Go("DealGob.Deal", g, g, done) +} diff --git a/rpc/Rpc_test.go b/rpc/Rpc_test.go new file mode 100644 index 0000000..506351f --- /dev/null +++ b/rpc/Rpc_test.go @@ -0,0 +1,60 @@ +package part + +import ( + "errors" + "testing" + "time" +) + +func TestMain(t *testing.T) { + pob := Pob{Host: "127.0.0.1:10902", Path: "/123"} + if shutdown, e := pob.Server(func(i, o *Gob) error { + if iv, ok := i.Data.(int); !ok { + return errors.New("iv") + } else { + switch i.Key { + case "+": + o.Data = iv + 1 + case "-": + o.Data = iv - 1 + default: + return errors.New("no key") + } + } + return nil + }); e != nil { + t.Fatal(e) + } else { + defer shutdown() + } + + time.Sleep(time.Second) + + if c, e := pob.Client(); e != nil { + t.Fatal(e) + } else { + var gob = Gob{"+", 9} + if e := c.Call(&gob); e != nil { + t.Fatal(e) + } else if gob.Key != "+" { + t.Fatal() + } else if i, ok := gob.Data.(int); !ok || i != 10 { + t.Fatal() + } + c.Close() + } + + if c, e := pob.Client(); e != nil { + t.Fatal(e) + } else { + var gob = Gob{"-", 9} + if e := c.Call(&gob); e != nil { + t.Fatal(e) + } else if gob.Key != "-" { + t.Fatal() + } else if i, ok := gob.Data.(int); !ok || i != 8 { + t.Fatal() + } + c.Close() + } +} -- 2.39.2