func TestServer(t *testing.T) { log.Debugf("Enter TestServer..") numTimeout := 0 numUnmatch := 0 numSuccess := 0 for i := 0; i < 10000; i++ { val := RandStringBytes() log.Infof("loop: %d. msg len: %d", i, len(val)) msg := NewReqMsg(ENCODE_TYPE_JSON, 3, []byte(val)) log.Debugf("request msg: %s", msg.String()) c.SendReq(addr, msg) respMsg, _ := c.GetRespBlock(msg.sessionId) if respMsg.pCode == MSG_TIMEOUT { numTimeout++ continue } if string(respMsg.data) != val { numUnmatch++ t.Error("not match ", val, string(respMsg.data)) } else { numSuccess++ } } log.Infof("\nnumUnmatch: %d\nnumTimeout: %d\nnumSuccess: %d", numUnmatch, numTimeout, numSuccess) }
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 }