code: func NewMConnectionWithConfig(conn net.Conn, chDescs []*ChannelDescriptor, onReceive receiveCbFunc, onError errorCbFunc, config *MConnConfig) *MConnection {
  	mconn := &MConnection{
  		conn:        conn,
  		bufReader:   bufio.NewReaderSize(conn, minReadBufferSize),
  		bufWriter:   bufio.NewWriterSize(conn, minWriteBufferSize),
  		sendMonitor: flow.New(0, 0),
  		recvMonitor: flow.New(0, 0),
  		send:        make(chan struct{}, 1),
  		pong:        make(chan struct{}),
  		onReceive:   onReceive,
  		onError:     onError,
  		config:      config,
  
  		LocalAddress:  NewNetAddress(conn.LocalAddr()),
  		RemoteAddress: NewNetAddress(conn.RemoteAddr()),
  	}
  
  	// Create channels
  	var channelsIdx = map[byte]*Channel{}
  	var channels = []*Channel{}
  
  	for _, desc := range chDescs {
  		descCopy := *desc // copy the desc else unsafe access across connections
  		channel := newChannel(mconn, &descCopy)
  		channelsIdx[channel.id] = channel
  		channels = append(channels, channel)
  	}
  	mconn.channels = channels
  	mconn.channelsIdx = channelsIdx
  
  	mconn.BaseService = *cmn.NewBaseService(log, "MConnection", mconn)
  
  	return mconn
  }
docs: // NewMConnectionWithConfig wraps net.Conn and creates multiplex connection with a config