func (mp *Multiplex) CloseChan() <-chan struct{} {
	return mp.closed
}
CloseChan returns a read-only channel which will be closed when the session is closed
package multiplex
import (
	"bufio"
	"context"
	"encoding/binary"
	"errors"
	"fmt"
	"io"
	"net"
	"sync"
	"time"
	logging "github.com/ipfs/go-log"
	pool "github.com/libp2p/go-buffer-pool"
	"github.com/multiformats/go-varint"
)
var log = logging.Logger("mplex")
var MaxMessageSize = 1 << 20
var ReceiveTimeout = 5 * time.Second
var ErrShutdown = errors.New("session shut down")
var ErrTwoInitiators = errors.New("two initiators")
var ErrInvalidState = errors.New("received an unexpected message from the peer")
var errTimeout = timeout{}
var (
	ResetStreamTimeout = 2 * time.Minute
	WriteCoalesceDelay = 100 * time.Microsecond
)
type timeout struct{}
func (timeout) Error() string {
	return "i/o deadline exceeded"
}
func (timeout) Temporary() bool {
	return true
}
func (timeout) Timeout() bool {
	return true
}
const (
	newStreamTag = 0
	messageTag   = 2
	closeTag     = 4
	resetTag     = 6
)
type Multiplex struct {
	con       net.Conn
	buf       *bufio.Reader
	nextID    uint64
	initiator bool
	closed       chan struct{}
	shutdown     chan struct{}
	shutdownErr  error
	shutdownLock sync.Mutex
	writeCh         chan []byte
	writeTimer      *time.Timer
	writeTimerFired bool
	nstreams chan *Stream
	channels map[streamID]*Stream
	chLock   sync.Mutex
}
func NewMultiplex(con net.Conn, initiator bool) *Multiplex {
	mp := &Multiplex{
		con:        con,
		initiator:  initiator,
		buf:        bufio.NewReader(con),
		channels:   make(map[streamID]*Stream),
		closed:     make(chan struct{}),
		shutdown:   make(chan struct{}),
		writeCh:    make(chan []byte, 16),
		writeTimer: time.NewTimer(0),
		nstreams:   make(chan *Stream, 16),
	}
	go mp.handleIncoming()
	go mp.handleOutgoing()
	return mp
}
func (mp *Multiplex) newStream(id streamID, name string) (s *Stream) {
	s = &Stream{
		id:          id,
		name:        name,
		dataIn:      make(chan []byte, 8),
		rDeadline:   makePipeDeadline(),
		wDeadline:   makePipeDeadline(),
		mp:          mp,
		writeCancel: make(chan struct{}),
		readCancel:  make(chan struct{}),
	}
	return
}
func (m *Multiplex) Accept() (*Stream, error) {
	select {
	case s, ok := <-m.nstreams:
		if !ok {
			return nil, errors.New("multiplex closed")
		}
		return s, nil
	case <-m.closed:
		return nil, m.shutdownErr
	}
}
func (mp *Multiplex) Close() error {
	mp.closeNoWait()
	<-mp.closed
	return nil
}
func (mp *Multiplex) closeNoWait() {
	mp.shutdownLock.Lock()
	select {
	case <-mp.shutdown:
	default:
		mp.con.Close()
		close(mp.shutdown)
	}
	mp.shutdownLock.Unlock()
}
func (mp *Multiplex) IsClosed() bool {
	select {
	case <-mp.closed:
		return true
	default:
		return false
	}
}