If my client program sends OpText and OpBinary data regularly, it will not disconnect.
But I send OpPing regularly, and the server program also returns OpPong. It will automatically disconnect after 30 seconds, and 30 seconds is always fixed.
// server
go func() {
defer func() {
if err := recover(); err != nil {
buf := make([]byte, 1<<16)
stackSize := runtime.Stack(buf, true)
logger.Errorf("client occur panic, err: %v, stack: %s", err, string(buf[0:stackSize]))
}
logger.Infof("Client [%s] HUP disconnected", client.id)
if wh.srv.OnDisconnect != nil {
go wh.srv.OnDisconnect(client)
}
// _ = w.epoller.del(client.fd)
wh.srv.Lock()
delete(wh.srv.clients, client.ID())
wh.srv.Unlock()
_ = client.conn.Close()
}()
for {
// set SetReadDeadline
err := conn.SetReadDeadline(time.Time{})
if err != nil {
logger.Errorf("SetReadDeadline failed: %s", err)
// do something else, for example create new conn
return
}
messages, err := wsutil.ReadClientMessage(client.conn, []wsutil.Message{})
if err != nil { // Read error
logger.Infof("Websocket read error from client [%s] - %s", client.ID(), err)
return
}
for _, msg := range messages {
switch msg.OpCode {
case ws.OpText, ws.OpBinary:
if wh.srv.OnData == nil {
logger.Errorf("websocket handler on data handler not setting, body: %s", string(msg.Payload))
return
}
if err = wh.srv.OnData(client, msg.Payload); err != nil {
logger.Errorf("websocket handler data failure, body: %s err: %v", string(msg.Payload), err)
}
case ws.OpClose: // Close
logger.Infof("receive client closed")
case ws.OpPing: // Ping
logger.Infof("receive client ping control message")
if err := wsutil.WriteServerMessage(conn, ws.OpPong, nil); err != nil {
logger.Errorf("send pong control message failure, err: %v", err)
}
case ws.OpContinuation: // Continuation
logger.Infof("receive client continuation")
case ws.OpPong: // Pong
logger.Infof("receive pong....")
default: // WTF -_-!
logger.Errorf("receive error message from client: %s, op: %v", string(msg.Payload), msg.OpCode)
}
}
}
}()
// client
go func() {
defer func(conn net.Conn) {
logger.Infof("close conn")
err := conn.Close()
if err != nil {
logger.Infof("close conn error: %+v", err)
}
}(conn)
for {
err := conn.SetReadDeadline(time.Time{})
messages, err := wsutil.ReadServerMessage(conn, []wsutil.Message{})
if err != nil {
logger.Infof("read error: %+v", err)
return
}
logger.Infof("on receive message: %+v", messages)
for _, msg := range messages {
switch msg.OpCode {
case ws.OpText, ws.OpBinary:
if client.OnData != nil {
err := client.OnData(client, msg.Payload)
if err != nil {
logger.Infof("on receive data error: %s", err)
}
}
case ws.OpPing:
logger.Infof("on receive ping message")
_ = wsutil.WriteClientMessage(conn, ws.OpPong, nil)
case ws.OpPong:
logger.Infof("on receive pong message")
case ws.OpClose:
logger.Infof("on receive close message")
return
}
}
}
}()
go func() {
ticker := time.NewTicker(pingPeriod)
defer func() {
ticker.Stop()
_ = conn.Close()
}()
for {
select {
case <-ticker.C:
logger.Infof("ticker .......")
// _ = conn.SetWriteDeadline(time.Now().Add(writeWait))
//cmd := message.GenerateSimpleCommand(
// message.CommandPing,
//)
//err := wsutil.WriteClientMessage(conn, ws.OpText, cmd.Bytes())
err := wsutil.WriteClientMessage(conn, ws.OpPing, nil)
if err != nil {
logger.Infof("ticker write ....... %+v", err)
break
}
}
}
}()
If my client program sends OpText and OpBinary data regularly, it will not disconnect. But I send OpPing regularly, and the server program also returns OpPong. It will automatically disconnect after 30 seconds, and 30 seconds is always fixed.
// server
// client