neffos
neffos copied to clipboard
How to monitor client disconnect / close connection?
I want to do something when closing, or interrupting the client connection, such as cleaning up. I call conn.Close()
on ws.OnConnect{}
without triggering ws.OnDisconnect{}
. what should I do?
package main
import (
"fmt"
"github.com/kataras/iris/v12"
"github.com/kataras/iris/v12/websocket"
"github.com/kataras/neffos"
)
func main() {
app := iris.Default()
ws := neffos.New(websocket.DefaultGorillaUpgrader, neffos.Namespaces{
neffos.OnNativeMessage: neffos.Events{
"login": func(ns *neffos.NSConn, msg neffos.Message) error {
return nil
},
},
})
ws.OnConnect = func(conn *neffos.Conn) error {
allowConnect = true
// some operations...
if !allowConnect {
conn.Close()
}
return nil
}
ws.OnDisconnect = func(c *neffos.Conn) {
// No shutdown signal is received and the method body is not triggered.
fmt.Println("OnDisconnect")
}
app.Get("/login", websocket.Handler(ws))
app.Logger().Fatal(app.Listen(":8080"))
}
@hjzCy You can't close the connection immediately from the ws.OnConnect
event. If you want to close the connection from OnConnect you should return a NON-NIL ERROR. Also, there is a note on the code at:
https://github.com/kataras/neffos/blob/f1431864185db0b334b82e3817eb03bd957f9fda/server.go#L174-L179
We can change that if you want by an option(in order to not break existing behavior).
However, if you wait 1 second, it will be fired, although there is no logic on closing the connection without any checks when it's just connected (that's why we have the above check in the code too):
ws.OnConnect = func(conn *neffos.Conn) error {
time.Sleep(time.Second)
conn.Close()
return nil
}
OK @hjzCy, a FireDisconnectAlways
option was added.
$ go get github.com/kataras/[email protected]
# or go.mod:
# require github.com/kataras/neffos v0.0.16
ws := neffos.New([...])
ws.FireDisconnectAlways = true // <---HERE
ws.OnConnect = func(conn *neffos.Conn) error {
conn.Close()
return nil
}
ws.OnDisconnect = func(conn *neffos.Conn) {
log.Printf("[%s] disconnected from the server.", c)
}
@kataras Thank you!very perfect!
@kataras
After setting FireDisconnectAlways = true
, if the client suddenly disconnects, any data you want to get from the conn
of the OnDisconnect{}
method is invalid. And may cause the program to crash:
ws.OnDisconnect = apis.Logout
func Logout(conn *neffos.Conn) {
ctx := websocket.GetContext(conn)
token := strings.ReplaceAll(ctx.URLParam("token"), " ", "+")
decode := aes.CBCDecrypt(token)
// If `FireDisconnectAlways = false` then data can be obtained normally
fmt.Println("token:", token)
fmt.Println("decode:", decode)
// If `FireDisconnectAlways = false`, it will execute normally.
// Otherwise, the program will crash directly here ( Out of range )!!
username := decode[:strings.Index(decode, ", ")]
if client, ok := loginClients[username]; ok {
if client.topStatus {
log.Println("顶号断开连接,不删除用户数据。将顶号状态设置为 false。")
client.topStatus = false
} else {
log.Println("异常、或正常断开连接,删除用户数据。")
delete(loginClients, username)
}
}
}
The question now is that after the client disconnects, the data returned from conn
is invalid. How can I still get the data from theOnDisconnect {}
method after the client disconnects? E.g,Want to get the url parameter of this connection:
ctx := websocket.GetContext(conn)
fmt.Println("token:", ctx.URLParam("token")) // get failed, token is ""
@hjzCy The connection is already closed and removed from the server when ws.OnDisconnect
is fired (see https://github.com/kataras/neffos/blob/15e3a17ca8e37b9e793fd59811e7fb42a30ac5ee/conn.go#L1039). Why you don't use the neffos.OnNamespaceDisconnect
event instead? It will be called on your conn.Close()
too.
@kataras I cannot use neffos.OnNamespaceDisconnect
because I need to use neffos.OnNativeMessage
and my python client cannot connect to the namespace.
@kataras The two problems above are that I didn't manually call conn.Close ()
, but when the client disconnected, ws.OnDisconnect` received the signal automatically.
没有手动调用 conn.Close()
,而是客户端由于某种原因断开了连接,此时 ws.OnDisconnect
接收到信号:
ws.OnDisconnect = apis.Logout
func Logout(conn *neffos.Conn) {
ctx := websocket.GetContext(conn)
// FireDisconnectAlways = false can get the result normally, otherwise "".
fmt.Println("token:", ctx.URLParam("token"))
}
Cannot get url parameter data.
Well, I found that even if FireDisconnectAlways = true
, sometimes when the client is suddenly disconnected, the conn
data stored in the ws.OnDisconnect ()
method cannot be obtained.
A suggestion:
Is it possible to wait until the body of the ws.OnDisconnect()
method is executed, and then disconnect from the conn
, so that you can do some things by getting the data of conn
when disconnecting.
Or add a signal: ws.onWillDisconnect()
?