Closed AnirudhDensityIntern closed 6 months ago
yes
I think the best practice is:
In nbio, you need just set upgrader.KeepaliveTime = yourKeepaliveInterval
then nbio will update ReadDeadline itself when receiving a message, nbio also replies a pong message to a ping message automatically.
So, maybe that's all you need to do except ask the client side to send the keepalive ping messages themselves.
I want to make a dynamic ping message as text and insure that pong message as a text is received against that at particular time interval, lets say every 20 second.
Although sending ping msg on the server-side can do that keepalive things and many people design their code like that, it's a little waste. server-side check read deadline would be better for server-side cost.
But if you want to do that:
upgrader.SetPongHandler(yourPingHandler)
of course you should update read deadline by wsConn.SetReadDeadline(time.Now().Add(...))
in yourPongHandler or
set upgrader.KeepaliveTime=...
and
wsConn.WriteMessage(PingMessage, []byte("your text"))
in your self timer
we are set the conn.SetDeadline to 10 second and then we send the pong message inside the ping handler we getting the ping timeout in this case.
when we write the message there is no error but still get the pong message timeout.
this we get in close handler"reason\\\":\\\"read timeout\\\"
func (u *userStreamImpl) pingHandler(userID uuid.UUID) func(conn *websocket.Conn, s string) {
return func(conn *websocket.Conn, s string) {
u.logger.Debug("websocket ping received", log.Any("userID", userID))
err := conn.SetDeadline(time.Now().Add(10 * time.Second))
fmt.Println(err)
err = conn.WriteMessage(websocket.PongMessage, []byte{})
fmt.Println(err)
time.Sleep(8 * time.Second)
err = conn.SetDeadline(time.Time{})
//err = conn.WriteMessage(websocket.TextMessage, []byte("{\"hello dude\": \"jhehd\"}"))
if err != nil {
u.logger.Error("websocket ping handler failed", log.Error(err), log.Any("userID", userID))
u.publishCloseMessage(userID, "websocket ping handler failed")
}
}
}
1st, you should reply to the ping message as soon as you receive it
2nd, you shouldn't time.Sleep(8 * time.Second)
in a message handler, that will make the goroutine blocking for long, and may use out the goroutine pool.
we are using that without time.sleep we are replying that without sleep still getting read timeout error in close handler
Show me the full examples including both client and server sides that can reproduce it!
Your previous example is the wrong implementation.
func (u *userStreamImpl) pingHandler(userID uuid.UUID) func(conn *websocket.Conn, s string) {
return func(conn *websocket.Conn, s string) {
u.logger.Debug("websocket ping received", log.Any("userID", userID))
err = conn.WriteMessage(websocket.PongMessage, []byte{})
if err != nil {
u.logger.Error("websocket ping handler failed", log.Error(err), log.Any("userID", userID))
u.publishCloseMessage(userID, "websocket ping handler failed")
}
}
}
we are managing only on server side to call different backend services for the broker
func (u *userStreamImpl) pingHandler(userID uuid.UUID) func(conn *websocket.Conn, s string) { return func(conn *websocket.Conn, s string) { u.logger.Debug("websocket ping received", log.Any("userID", userID)) err = conn.WriteMessage(websocket.PongMessage, []byte{}) if err != nil { u.logger.Error("websocket ping handler failed", log.Error(err), log.Any("userID", userID)) u.publishCloseMessage(userID, "websocket ping handler failed") } } }
Please provide the full example that I can run directly. That's not all the details.
This issue is stale because it has been open for 30 days with no activity.
This issue was closed because it has been inactive for 14 days since being marked as stale.
What do you want to implement exactly? Is it for keepalive?