func (server *TcpServer) Start() { for { // check if need to stop the loop.. select { case <-server.stopChan: server.mu.Lock() for addr, conn := range server.connMap { delete(server.connMap, addr) conn.Disconnect() } server.mu.Unlock() default: } conn, err := server.listener.Accept() if err != nil { log.WarnErrorf(err, "Accept Error.") return } log.Infof("Accept connection from %s", conn.RemoteAddr().String()) go func(conn net.Conn) { connection := NewConnection(conn, true, -1) server.safeAddConn(connection) for { msg := connection.ReceiveMsg() if msg == nil { server.safeDeleteConn(connection.addr) connection.Disconnect() return } msg.SetConnection(connection) // log.Debugf("[Server] Get msg: %s", msg.String()) server.reqChan <- msg } }(conn) } }
// this function don't need lock, we will lock in the caller func (client *TcpClient) createConnection(addr string) *Connection { conn, err := net.Dial("tcp", addr) if err != nil { log.WarnErrorf(err, "Can't dail to %s", addr) return nil } connection := NewConnection(conn, false, -1) //move all the response from this connection to session channel go func(c *Connection) { for { msg := c.ReceiveMsg() if msg == nil { c.Disconnect() return } // move this message to session channel. sessionId := msg.sessionId client.sessionMtx.RLock() session, ok := client.sessionMap[sessionId] if ok { select { case session.sessionChan <- msg: log.Debugf("Write reponse for session(%d) to channel", sessionId) default: log.Infof("session(%d) is timeout..", sessionId) } } else { log.Warnf("A bug or a wrong message, because we can't find session(%d)", sessionId) } client.sessionMtx.RUnlock() } }(connection) return connection }