You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm currently having some issues understanding what the expected implementation is for handling pings and pongs in a repeated fashion, primarily being used as a "heartbeat" indicator so I can free specific connections so I'm not sending data to socket connections which aren't active. I read over #186 and took a look at both of the examples in the repo and am trying to determine a few things:
I'm using wsjson.Read to read in requested data, as opposed to using the Reader / Read functions. This data is a JSON marshalled form of the struct listed below:
The type has a value, whether that's "init", "register", or "unregister". During "init", we'll perform some mapping and then call a go routine called Ping, providing the pointer the websocket.Conn. The desired implementation is basically to ping every 30 seconds or so and then after a few failures it'll unlisted it.
Is the pong response supposed to be automatically handled by the call to the connection's Ping function? Is this something that would be in the response handler (e.g. func SocketHandler(w http.ResponseWriter, r *http.Request)) instead? Or am I just missing something or going about it the wrong way.
Here's something I was testing, not actually functional but should give some idea on the context:
Holy smokes that was a quick response, thanks for the additional information. Here are the two functions, do you see anything obvious that would indicate why at least in Firefox it isn't indicating ping / pong responses in its Messages tab (it seems to receive a ping once, send a pong, then nothing after that).
// Ping the client will attempt to regularly ping the clientfuncPing(c*websocket.Conn) {
for {
ctx, _:=context.WithTimeout(context.Background(), time.Second*15)
trunk.LogInfo("Pinging client")
pingErr:=c.Ping(ctx)
ifpingErr==nil {
trunk.LogSuccess("Pinged client")
time.Sleep(time.Second*30)
} else {
trunk.LogErr("Failed to ping client")
RemoveConn(socketConn, "all", "all")
}
}
}
// SocketHandler will handle any request to registration and unregistration of a WebSocket ConnectionfuncSocketHandler(w http.ResponseWriter, r*http.Request) {
socketConn, acceptErr:=websocket.Accept(w, r, &websocket.AcceptOptions{
Subprotocols: []string{
"sbd-v0.1", // 0.1
},
InsecureSkipVerify: core.Conf.Servers.WebSockets.DisableOriginVerification,
})
ifacceptErr!=nil {
return
}
varrequestWebSocketEventifreadErr:=wsjson.Read(r.Context(), socketConn, &request); readErr!=nil { // Read contentsreturn
}
ifrequest.Type=="init" {
initErr:=SocketInitHandler(socketConn, request)
ifinitErr==nil {
goPing(socketConn)
}
} elseifrequest.Type=="register" { // RegisterSocketRegisterHandler(socketConn, request)
} elseifrequest.Type=="unregister" { // UnregisterSocketUnregisterHandler(socketConn, request) // Call to unregister
} else { // Neither typesocketConn.Close(websocket.StatusUnsupportedData, "Type specified is invalid")
}
}
So is wsjson.Read expected to fail unmarshalling the pong given it isn't actually that struct?
Holy smokes that was a quick response, thanks for the additional information.
🚀
Here are the two functions, do you see anything obvious that would indicate why at least in Firefox it isn't indicating ping / pong responses in its Messages tab (it seems to receive a ping once, send a pong, then nothing after that).
You need to keep reading from the connection in SocketHandler. You can use CloseRead if you don't expect any data messages as is your case.
Also, not sure if it's just the example code you've provided but there are codepaths where the connection isn't closed. I'd recommend using CloseRead after you read the JSON and then calling Ping in the SocketHandler goroutine instead of a separate one.
So is wsjson.Read expected to fail unmarshalling the pong given it isn't actually that struct?
wsjson.Read just tells the Ping goroutine it's received a pong and then continues reading data messages. It doesn't unmarshal the pong.
Hey, not to necro this, but after some tinkering I was able to get pinging and the use of the CloseRead to work as I expected thanks to your advise and pointers. So, thank you. Your time is genuinely much appreciated, both working on this as well as providing support.
Reacted by Adam Quinn Snow, ryanerwin, Cesar Arguello and Jeff
Activity
nhooyr commentedon Apr 22, 2020
Hi,
Ping will block until the goroutine in
wjson.Readreads the pong from the peer or the deadline is hit.I've opened #227 to add an example to make this more clear.
nhooyr commentedon Apr 22, 2020
So your code should work as long as
Pingruns in a different goroutine than the one inwsjson.Read.JoshStrobl commentedon Apr 22, 2020
Holy smokes that was a quick response, thanks for the additional information. Here are the two functions, do you see anything obvious that would indicate why at least in Firefox it isn't indicating ping / pong responses in its Messages tab (it seems to receive a ping once, send a pong, then nothing after that).
So is wsjson.Read expected to fail unmarshalling the
ponggiven it isn't actually that struct?nhooyr commentedon Apr 22, 2020
🚀
You need to keep reading from the connection in SocketHandler. You can use
CloseReadif you don't expect any data messages as is your case.Also, not sure if it's just the example code you've provided but there are codepaths where the connection isn't closed. I'd recommend using
CloseReadafter you read the JSON and then callingPingin theSocketHandlergoroutine instead of a separate one.wsjson.Read just tells the
Pinggoroutine it's received a pong and then continues reading data messages. It doesn't unmarshal the pong.JoshStrobl commentedon Apr 23, 2020
Hey, not to necro this, but after some tinkering I was able to get pinging and the use of the CloseRead to work as I expected thanks to your advise and pointers. So, thank you. Your time is genuinely much appreciated, both working on this as well as providing support.
nhooyr commentedon Apr 23, 2020
Thank you Joshua, I really appreciate that <3