...
1
2
3
4
5 package jsonrpc
6
7 import (
8 "encoding/json"
9 "errors"
10 "io"
11 "net/rpc"
12 "sync"
13 )
14
15 var errMissingParams = errors.New("jsonrpc: request body missing params")
16
17 type serverCodec struct {
18 dec *json.Decoder
19 enc *json.Encoder
20 c io.Closer
21
22
23 req serverRequest
24
25
26
27
28
29
30
31 mutex sync.Mutex
32 seq uint64
33 pending map[uint64]*json.RawMessage
34 }
35
36
37 func NewServerCodec(conn io.ReadWriteCloser) rpc.ServerCodec {
38 return &serverCodec{
39 dec: json.NewDecoder(conn),
40 enc: json.NewEncoder(conn),
41 c: conn,
42 pending: make(map[uint64]*json.RawMessage),
43 }
44 }
45
46 type serverRequest struct {
47 Method string `json:"method"`
48 Params *json.RawMessage `json:"params"`
49 Id *json.RawMessage `json:"id"`
50 }
51
52 func (r *serverRequest) reset() {
53 r.Method = ""
54 r.Params = nil
55 r.Id = nil
56 }
57
58 type serverResponse struct {
59 Id *json.RawMessage `json:"id"`
60 Result interface{} `json:"result"`
61 Error interface{} `json:"error"`
62 }
63
64 func (c *serverCodec) ReadRequestHeader(r *rpc.Request) error {
65 c.req.reset()
66 if err := c.dec.Decode(&c.req); err != nil {
67 return err
68 }
69 r.ServiceMethod = c.req.Method
70
71
72
73
74 c.mutex.Lock()
75 c.seq++
76 c.pending[c.seq] = c.req.Id
77 c.req.Id = nil
78 r.Seq = c.seq
79 c.mutex.Unlock()
80
81 return nil
82 }
83
84 func (c *serverCodec) ReadRequestBody(x interface{}) error {
85 if x == nil {
86 return nil
87 }
88 if c.req.Params == nil {
89 return errMissingParams
90 }
91
92
93
94
95 var params [1]interface{}
96 params[0] = x
97 return json.Unmarshal(*c.req.Params, ¶ms)
98 }
99
100 var null = json.RawMessage([]byte("null"))
101
102 func (c *serverCodec) WriteResponse(r *rpc.Response, x interface{}) error {
103 c.mutex.Lock()
104 b, ok := c.pending[r.Seq]
105 if !ok {
106 c.mutex.Unlock()
107 return errors.New("invalid sequence number in response")
108 }
109 delete(c.pending, r.Seq)
110 c.mutex.Unlock()
111
112 if b == nil {
113
114 b = &null
115 }
116 resp := serverResponse{Id: b}
117 if r.Error == "" {
118 resp.Result = x
119 } else {
120 resp.Error = r.Error
121 }
122 return c.enc.Encode(resp)
123 }
124
125 func (c *serverCodec) Close() error {
126 return c.c.Close()
127 }
128
129
130
131
132 func ServeConn(conn io.ReadWriteCloser) {
133 rpc.ServeCodec(NewServerCodec(conn))
134 }
135
View as plain text