Newer
Older
)
var (
ErrClientQuit = errors.New("client is closed")
ErrNoResult = errors.New("no result in JSON-RPC response")
ErrSubscriptionQueueOverflow = errors.New("subscription queue overflow")
errClientReconnected = errors.New("client reconnected")
errDead = errors.New("connection lost")
)
var DefaultH2CClient = &http.Client{
Transport: &http2.Transport{
// So http2.Transport doesn't complain the URL scheme isn't 'https'
AllowHTTP: true,
// Pretend we are dialing a TLS endpoint. (Note, we ignore the passed tls.Config)
DialTLSContext: func(ctx context.Context, network, addr string, cfg *tls.Config) (net.Conn, error) {
var d net.Dialer
return d.DialContext(ctx, network, addr)
},
},
}
c.handler = c.m.HandlerFunc(func(w jsonrpc.ResponseWriter, r *jsonrpc.Request) {
}
func DialHTTP(target string) (*Client, error) {
return Dial(nil, http.DefaultClient, target)
func DialH2C(target string) (*Client, error) {
return Dial(nil, DefaultH2CClient, target)
}
func Dial(ctx context.Context, client *http.Client, target string) (*Client, error) {
return &Client{remote: target, c: client, headers: http.Header{
"Content-Type": []string{"application/json"},
}}, nil
func (c *Client) Do(ctx context.Context, result any, method string, params any) error {
req, err := jsonrpc.NewRequest(ctx, jsonrpc.NewId(c.id.Add(1)), method, params)
StatusCode: resp.StatusCode,
Status: resp.Status,
Body: b,
}
}
if result != nil && msg.Result != nil {
err = json.NewDecoder(msg.Result).Decode(result)
func (c *Client) Notify(ctx context.Context, method string, params any) error {
func (c *Client) Closed() <-chan struct{} {
return make(chan struct{})
}
buf.Reset()
err := json.NewEncoder(buf).Encode(req)
if err != nil {
return nil, err
}
resp, err := c.postBuf(req.Context(), buf)
if err != nil {
return nil, err
}
return resp, nil
}
func (c *Client) postBuf(ctx context.Context, rd io.Reader) (*http.Response, error) {
if ctx == nil {
ctx = context.Background()
}
hreq, err := http.NewRequestWithContext(ctx, http.MethodPost, c.remote, rd)
if err != nil {
return nil, err
}
func() {
c.mu.RLock()
defer c.mu.RUnlock()
for k, v := range c.headers {
for _, vv := range v {
hreq.Header.Add(k, vv)
}
}
}()
return c.c.Do(hreq)
}