jsonrpc2.go
func (c *Conn) Call(ctx context.Context, method string, params, result interface{}, opts ...CallOption) error {
	req := &Request{Method: method}
	if err := req.SetParams(params); err != nil {
		return err
	}
	for _, opt := range opts {
		if opt == nil {
			continue
		}
		if err := opt.apply(req); err != nil {
			return err
		}
	}
	call, err := c.send(ctx, &anyMessage{request: req}, true)
	if err != nil {
		return err
	}
	select {
	case err, ok := <-call.done:
		if !ok {
			err = ErrClosed
		}
		if err != nil {
			return err
		}
		if result != nil {
			if call.response.Result == nil {
				call.response.Result = &jsonNull
			}
			// TODO(sqs): error handling
			if err := json.Unmarshal(*call.response.Result, result); err != nil {
				return err
			}
		}
		return nil

	case <-ctx.Done():
		return ctx.Err()
	}
}
func (c *Conn) Call(ctx context.Context, method string, params, result interface{}, opts ...CallOption) error {
	req := &Request{Method: method}
	if err := req.SetParams(params); err != nil {
		return err
	}
	for _, opt := range opts {
		if opt == nil {
			continue
		}
		if err := opt.apply(req); err != nil {
			return err
		}
	}
	call, err := c.send(ctx, &anyMessage{request: req}, true)
	if err != nil {
		return err
	}
	select {
	case err, ok := <-call.done:
		if !ok {
			err = ErrClosed
		}
		if err != nil {
			return err
		}
		if result != nil {
			if call.response.Result == nil {
				call.response.Result = &jsonNull
			}
			// TODO(sqs): error handling
			if err := json.Unmarshal(*call.response.Result, result); err != nil {
				return err
			}
		}
		return nil

	case <-ctx.Done():
		return ctx.Err()
	}
}
// Call initiates a JSON-RPC call using the specified method and
// params, and waits for the response. If the response is successful,
// its result is stored in result (a pointer to a value that can be
// JSON-unmarshaled into); otherwise, a non-nil error is returned.