func NewManager(c *cdp.Client) (*Manager, error) {
	m := &Manager{
		c:    c,
		sC:   make(chan *session),
		errC: make(chan error, 1),
	}
	m.ctx, m.cancel = context.WithCancel(context.TODO())
	ev, err := newSessionEvents(m.ctx, c)
	if err != nil {
		close(m.errC)
		m.Close()
		return nil, err
	}
	m.done = make(chan error, 1)
	go m.watch(ev, m.sC, m.done, m.errC)
	return m, nil
}
NewManager creates a new session Manager.

The cdp.Client will be used to listen to events and invoke commands
on the Target domain. It will also be used by all rpcc.Conn created
by Dial.
package session
import (
	"context"
	"time"
	"github.com/mafredri/cdp"
	"github.com/mafredri/cdp/internal/errors"
	"github.com/mafredri/cdp/protocol/target"
	"github.com/mafredri/cdp/rpcc"
)
type Manager struct {
	ctx    context.Context
	cancel context.CancelFunc
	c    *cdp.Client
	sC   chan *session
	done chan error
	errC chan error
}
const (
	defaultDetachTimeout = 5 * time.Second
)
func (m *Manager) Dial(ctx context.Context, id target.ID) (*rpcc.Conn, error) {
	s, err := dial(ctx, id, m.c, defaultDetachTimeout)
	if err != nil {
		return nil, err
	}
	select {
	case m.sC <- s:
	case <-m.ctx.Done():
		s.Close()
		return nil, errors.New("session.Manager: Dial failed: Manager is closed")
	}
	return s.Conn(), nil
}
func (m *Manager) Close() error {
	m.cancel()
	if m.done != nil {
		return errors.Wrapf(<-m.done, "session.Manager: close failed")
	}
	return nil
}
func (m *Manager) watch(ev *sessionEvents, created <-chan *session, done, errC chan<- error) {
	defer ev.Close()
	isClosing := func(err error) bool {
		switch cdp.ErrorCause(err) {
		case rpcc.ErrConnClosing, context.Canceled:
			m.cancel()
			return true
		}
		return false
	}
	sessions := make(map[target.SessionID]*session)
	defer func() {
		var err []error
		for _, ss := range sessions {
			err = append(err, ss.Close())
		}
		done <- errors.Merge(err...)
		close(done)
		close(errC)
	}()
	for {
		select {
		case s := <-created:
			sessions[s.ID] = s
		case <-ev.detached.Ready():
			ev, err := ev.detached.Recv()
			if err != nil {
				if isClosing(err) {
					return
				}
				err = errors.Wrapf(err, "Manager.watch: error receiving detached event")
				sendOrDiscardErr(errC, err)
				continue
			}
			if s, ok := sessions[ev.SessionID]; ok {
				delete(sessions, s.ID)
				s.Close()
			}
		case <-ev.message.Ready():
			ev, err := ev.message.Recv()
			if err != nil {
				if isClosing(err) {
					return
				}
				err = errors.Wrapf(err, "Manager.watch: error receiving message event")
				sendOrDiscardErr(errC, err)
				continue
			}
			if s, ok := sessions[ev.SessionID]; ok {
				err = s.Write([]byte(ev.Message))
				if err != nil {
					delete(sessions, s.ID)
				}
			}
		}
	}
}
func sendOrDiscardErr(errC chan<- error, err error) {
	select {
	case errC <- err:
	default:
	}
}
func (m *Manager) Err() <-chan error {
	return m.errC
}