func (c *Client) Close() error {
	c.Lock()
	if c.closed {
		return fmt.Errorf(`Double close`)
	}
	c.closed = true
	close(c.quitChan)
	for id := range c.pending {
		close(c.pending[id])
		delete(c.pending, id)
	}
	for method := range c.handlers {
		delete(c.handlers, method)
	}
	err := c.conn.Close()
	c.Unlock()
	return err
}
Close the client connection, not further use of the Client is permitted after
this method has been called.
package kodirpc
import (
	"encoding/json"
	"fmt"
	"io"
	"math"
	"net"
	"sync"
	"time"
)
const (
	backoff = 10 * time.Millisecond
)
type NotificationHandler func(method string, data interface{})
type Error struct {
	Code    int         `json:"code"`
	Message string      `json:"message"`
	Data    interface{} `json:"data,omitempty"`
}
func (e *Error) Error() string {
	return fmt.Sprintf("%s [code: %d]", e.Message, e.Code)
}
type request struct {
	Version string      `json:"jsonrpc"`
	Method  *string     `json:"method,omitempty"`
	Params  interface{} `json:"params,omitempty"`
	ID      *uint64     `json:"id,omitempty"`
}
type response struct {
	Result interface{} `json:"result,omitempty"`
	Error  *Error      `json:"error,omitempty"`
	request
}
type Client struct {
	address string
	config  *Config
	conn    io.ReadWriteCloser
	enc     *json.Encoder
	dec     *json.Decoder
	pending  map[uint64]chan response
	handlers map[string][]NotificationHandler
	seq      uint64
	quitChan chan struct{}
	closed bool
	sync.RWMutex
}