Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I encountered a problem of automatic disconnection after 30 seconds #202

Closed
TianLiangZhou opened this issue May 20, 2024 · 2 comments
Closed
Labels

Comments

@TianLiangZhou
Copy link

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
				}
			}
		}
	}()
@cristaloleg
Copy link
Collaborator

What was the problem?

@TianLiangZhou
Copy link
Author

@cristaloleg Other places are cleaned regularly 😭

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants