Sync takes two or more streams and sets them into synchronous operation,
relative to each other. This operation cannot be undone. If an error is
returned this function is no-op and the streams will continue in asynchronous
operation.

All streams must belong to the same Conn and they must not be closed. Passing
multiple streams of the same method to Sync is not supported and will return
an error.

A stream that is closed is removed and has no further affect on the streams
that were synchronized.

When two streams, A and B, are in sync they will both receive messages in the
order that they arrived on Conn. If a message for both A and B arrives, in
that order, it will not be possible to receive the message from B before the
message from A has been received.

type Codec interface {
// WriteRequest encodes and writes the request onto the
// underlying connection. Request is re-used between writes and
// references to it should not be kept.WriteRequest(*Request) error// ReadResponse decodes a response from the underlying
// connection. Response is re-used between reads and references
// to it should not be kept.ReadResponse(*Response) error
}

Codec is used by recv and dispatcher to
send and receive RPC communication.

SetCompressionLevel sets the flate compressions level for writes. Valid level
range is [-2, 9]. Returns error if compression is not enabled for Conn. See
package compress/flate for a description of compression levels.

WithWriteBufferSize returns a DialOption that sets the size of the write
buffer for the underlying websocket connection. Messages larger than this
size are fragmented according to the websocket specification.

The maximum buffer size for recent versions of Chrome is 104857586 (~100MB),
for older versions a maximum of 1048562 (~1MB) can be used. This is because
Chrome does not support websocket fragmentation.

type Stream interface {
// Ready returns a channel that is closed when a message is
// ready to be received via RecvMsg. Ready indicates that a call
// to RecvMsg is non-blocking.
//
// Ready must not be called concurrently while relying on the
// non-blocking behavior of RecvMsg. In this case both
// goroutines will be competing for the same message and one
// will block until the next message is available.
//
// Calling Close on the Stream will close the Ready channel
// indefinitely, pending messages may still be received via
// RecvMsg.
//
// Ready is provided for use in select statements.Ready() <-chan struct{}
// RecvMsg unmarshals pending messages onto m. Blocks until the
// next message is received, context is canceled or stream is
// closed.
//
// When m is a *[]byte the message will not be decoded and the
// raw bytes are copied into m.RecvMsg(m interface{}) error// Close closes the stream and no new messages will be received.
// RecvMsg will return ErrStreamClosing once all pending messages
// have been received.Close() error
}

☞ Chrome does not support websocket fragmentation
(continuation messages) or messages that exceed 1MB in size.
This limit was bumped in more recent versions of Chrome which can
receive messages up to 100MB in size.
See https://github.com/mafredri/cdp/issues/4 and
https://github.com/ChromeDevTools/devtools-protocol/issues/24.