@@ -6,6 +6,7 @@ package jsonrpc2
6
6
7
7
import (
8
8
"context"
9
+ "io"
9
10
"time"
10
11
11
12
"github.com/francoispqt/gojay"
@@ -16,15 +17,17 @@ import (
16
17
17
18
// Interface represents an interface for issuing requests that speak the JSON-RPC 2 protocol.
18
19
type Interface interface {
19
- Call (ctx context.Context , method string , params , result interface {}) error
20
+ io.ReadWriter
21
+
22
+ Call (ctx context.Context , method string , params , result interface {}) (err error )
20
23
21
24
Reply (ctx context.Context , req * Request , result interface {}, err error ) error
22
25
23
- Notify (ctx context.Context , method string , params interface {}) error
26
+ Notify (ctx context.Context , method string , params interface {}) ( err error )
24
27
25
28
Cancel (id ID )
26
29
27
- Run (ctx context.Context ) error
30
+ Run (ctx context.Context ) ( err error )
28
31
}
29
32
30
33
// Handler is an option you can pass to NewConn to handle incoming requests.
@@ -54,9 +57,10 @@ type Conn struct {
54
57
stream Stream
55
58
done chan struct {}
56
59
err error
57
- seq atomic.Int64 // must only be accessed using atomic operations
58
- pending atomic.Value // map[ID]chan *Response
59
- handling atomic.Value // map[ID]handling
60
+ ctx context.Context // for Read and Write only
61
+ seq atomic.Int64 // must only be accessed using atomic operations
62
+ pending atomic.Value // map[ID]chan *Response
63
+ handling atomic.Value // map[ID]handling
60
64
}
61
65
62
66
var _ Interface = (* Conn )(nil )
@@ -99,15 +103,13 @@ func WithOverloaded(overloaded bool) Options {
99
103
}
100
104
}
101
105
102
- var (
103
- defaultHandler = func (ctx context.Context , c * Conn , r * Request ) {
104
- if r .IsNotify () {
105
- c .Reply (ctx , r , nil , Errorf (CodeMethodNotFound , "method %q not found" , r .Method ))
106
- }
106
+ var defaultHandler = func (ctx context.Context , c * Conn , r * Request ) {
107
+ if r .IsNotify () {
108
+ c .Reply (ctx , r , nil , Errorf (CodeMethodNotFound , "method %q not found" , r .Method ))
107
109
}
110
+ }
108
111
109
- defaultCanceler = func (context.Context , * Conn , * Request ) {}
110
- )
112
+ var defaultCanceler = func (context.Context , * Conn , * Request ) {}
111
113
112
114
type handling struct {
113
115
request * Request
@@ -154,6 +156,16 @@ func NewConn(ctx context.Context, s Stream, options ...Options) *Conn {
154
156
return conn
155
157
}
156
158
159
+ // Read implements io.Reader.
160
+ func (c * Conn ) Read (p []byte ) (n int , err error ) {
161
+ return c .stream .Read (c .ctx , p )
162
+ }
163
+
164
+ // Write implements io.Write.
165
+ func (c * Conn ) Write (p []byte ) (n int , err error ) {
166
+ return c .stream .Write (c .ctx , p )
167
+ }
168
+
157
169
// Call sends a request over the connection and then waits for a response.
158
170
func (c * Conn ) Call (ctx context.Context , method string , params , result interface {}) error {
159
171
jsonParams , err := marshalToEmbedded (params )
@@ -196,7 +208,7 @@ func (c *Conn) Call(ctx context.Context, method string, params, result interface
196
208
zap .String ("req.method" , req .Method ),
197
209
zap .Any ("req.params" , req .Params ),
198
210
)
199
- if err := c .stream .Write (ctx , data ); err != nil {
211
+ if _ , err := c .stream .Write (ctx , data ); err != nil {
200
212
return err
201
213
}
202
214
@@ -216,10 +228,11 @@ func (c *Conn) Call(ctx context.Context, method string, params, result interface
216
228
if result == nil || resp .Result == nil {
217
229
return nil
218
230
}
219
- if err := gojay .Unsafe .Unmarshal (* resp .Result , result ); err != nil {
231
+ if err := gojay .Unsafe .Unmarshal (* resp .Result . EmbeddedJSON , result ); err != nil {
220
232
return xerrors .Errorf ("failed to unmarshalling result: %v" , err )
221
233
}
222
234
return nil
235
+
223
236
case <- ctx .Done ():
224
237
c .canceler (ctx , c , req )
225
238
return ctx .Err ()
@@ -242,14 +255,14 @@ func (c *Conn) Reply(ctx context.Context, req *Request, result interface{}, err
242
255
}
243
256
244
257
elapsed := time .Since (handling .start )
245
- var jsonParams * gojay. EmbeddedJSON
258
+ var raw * RawMessage
246
259
if err == nil {
247
- jsonParams , err = marshalToEmbedded (result )
260
+ raw , err = marshalToEmbedded (result )
248
261
}
249
262
250
263
resp := & Response {
251
264
ID : req .ID ,
252
- Result : jsonParams ,
265
+ Result : raw ,
253
266
}
254
267
255
268
if err != nil {
@@ -269,7 +282,7 @@ func (c *Conn) Reply(ctx context.Context, req *Request, result interface{}, err
269
282
zap .Error (resp .Error ),
270
283
)
271
284
272
- if err := c .stream .Write (ctx , data ); err != nil {
285
+ if _ , err := c .stream .Write (ctx , data ); err != nil {
273
286
return err
274
287
}
275
288
@@ -297,7 +310,9 @@ func (c *Conn) Notify(ctx context.Context, method string, params interface{}) er
297
310
zap .Any ("req.Params" , req .Params ),
298
311
)
299
312
300
- return c .stream .Write (ctx , data )
313
+ _ , err = c .stream .Write (ctx , data )
314
+
315
+ return err
301
316
}
302
317
303
318
// Cancel cancels a pending Call on the server side.
@@ -335,16 +350,16 @@ func (c *Conn) deliver(ctx context.Context, q chan queue, request *Request) bool
335
350
// combined has all the fields of both Request and Response.
336
351
// We can decode this and then work out which it is.
337
352
type combined struct {
338
- VersionTag Message `json:"jsonrpc"`
339
- ID * ID `json:"id,omitempty"`
340
- Method string `json:"method"`
341
- Params * gojay. EmbeddedJSON `json:"params,omitempty"`
342
- Result * gojay. EmbeddedJSON `json:"result,omitempty"`
343
- Error * Error `json:"error,omitempty"`
353
+ VersionTag Message `json:"jsonrpc"`
354
+ ID * ID `json:"id,omitempty"`
355
+ Method string `json:"method"`
356
+ Params * RawMessage `json:"params,omitempty"`
357
+ Result * RawMessage `json:"result,omitempty"`
358
+ Error * Error `json:"error,omitempty"`
344
359
}
345
360
346
361
// Run run the jsonrpc2 server.
347
- func (c * Conn ) Run (ctx context.Context ) error {
362
+ func (c * Conn ) Run (ctx context.Context ) ( err error ) {
348
363
q := make (chan queue , c .capacity )
349
364
defer close (q )
350
365
@@ -359,8 +374,9 @@ func (c *Conn) Run(ctx context.Context) error {
359
374
}()
360
375
361
376
for {
377
+ var data []byte
362
378
// get the data for a message
363
- data , err : = c .stream .Read (ctx )
379
+ _ , err = c .stream .Read (ctx , data )
364
380
if err != nil {
365
381
// the stream failed, we cannot continue
366
382
return err
@@ -458,12 +474,12 @@ func (d Direction) String() string {
458
474
}
459
475
}
460
476
461
- func marshalToEmbedded (obj interface {}) (* gojay. EmbeddedJSON , error ) {
477
+ func marshalToEmbedded (obj interface {}) (* RawMessage , error ) {
462
478
data , err := gojay .Marshal (obj )
463
479
if err != nil {
464
480
return nil , err
465
481
}
466
482
raw := gojay .EmbeddedJSON (data )
467
483
468
- return & raw , nil
484
+ return & RawMessage { EmbeddedJSON : & raw } , nil
469
485
}
0 commit comments