mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-08-02 16:08:31 +00:00
Use read deadlines instead of ping tickers
This commit is contained in:
parent
ea4909cdc6
commit
9c9fde0160
1 changed files with 39 additions and 14 deletions
|
@ -425,7 +425,24 @@ func runSocketReader(conn *websocket.Conn, client *ClientInfo, errorChan chan<-
|
||||||
defer close(errorChan)
|
defer close(errorChan)
|
||||||
defer close(clientChan)
|
defer close(clientChan)
|
||||||
|
|
||||||
for ; err == nil; messageType, packet, err = conn.ReadMessage() {
|
for {
|
||||||
|
conn.SetReadDeadline(time.Now().Add(1 * time.Minute))
|
||||||
|
messageType, packet, err = conn.ReadMessage()
|
||||||
|
// handle ReadDeadline by sending a ping
|
||||||
|
// writer loop handles repeated ping timeouts
|
||||||
|
if tmErr, ok := err.(interface {
|
||||||
|
Timeout() bool
|
||||||
|
}); ok && tmErr.Timeout() {
|
||||||
|
select {
|
||||||
|
case <-stoppedChan:
|
||||||
|
return
|
||||||
|
case clientChan <- ClientMessage{Command: "__readTimeout"}:
|
||||||
|
}
|
||||||
|
continue // re-set deadline and wait for pong packet
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
if messageType == websocket.BinaryMessage {
|
if messageType == websocket.BinaryMessage {
|
||||||
err = &CloseGotBinaryMessage
|
err = &CloseGotBinaryMessage
|
||||||
break
|
break
|
||||||
|
@ -448,23 +465,22 @@ func runSocketReader(conn *websocket.Conn, client *ClientInfo, errorChan chan<-
|
||||||
} else if msg.MessageID == 0 {
|
} else if msg.MessageID == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case clientChan <- msg:
|
|
||||||
case <-stoppedChan:
|
case <-stoppedChan:
|
||||||
return
|
return
|
||||||
|
case clientChan <- msg:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case errorChan <- err:
|
|
||||||
case <-stoppedChan:
|
case <-stoppedChan:
|
||||||
|
case errorChan <- err:
|
||||||
}
|
}
|
||||||
// exit goroutine
|
// exit goroutine
|
||||||
}
|
}
|
||||||
|
|
||||||
func runSocketWriter(conn *websocket.Conn, client *ClientInfo, errorChan <-chan error, clientChan <-chan ClientMessage, serverMessageChan <-chan ClientMessage) websocket.CloseError {
|
func runSocketWriter(conn *websocket.Conn, client *ClientInfo, errorChan <-chan error, clientChan <-chan ClientMessage, serverMessageChan <-chan ClientMessage) websocket.CloseError {
|
||||||
pingTicker := time.NewTicker(1 * time.Minute)
|
|
||||||
defer pingTicker.Stop()
|
|
||||||
lastPacket := time.Now()
|
lastPacket := time.Now()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
@ -485,12 +501,29 @@ func runSocketWriter(conn *websocket.Conn, client *ClientInfo, errorChan <-chan
|
||||||
}
|
}
|
||||||
|
|
||||||
case msg := <-clientChan:
|
case msg := <-clientChan:
|
||||||
|
if msg.Command == "__readTimeout" {
|
||||||
|
// generated on 60 seconds without a message
|
||||||
|
now := time.Now()
|
||||||
|
if lastPacket.Add(5 * time.Minute).Before(now) {
|
||||||
|
return CloseTimedOut
|
||||||
|
}
|
||||||
|
conn.WriteControl(
|
||||||
|
websocket.PingMessage,
|
||||||
|
[]byte(strconv.FormatInt(time.Now().Unix(), 10)),
|
||||||
|
getDeadline(),
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if !client.HelloOK && msg.Command != HelloCommand {
|
if !client.HelloOK && msg.Command != HelloCommand {
|
||||||
return CloseFirstMessageNotHello
|
return CloseFirstMessageNotHello
|
||||||
}
|
}
|
||||||
lastPacket = time.Now()
|
lastPacket = time.Now()
|
||||||
|
|
||||||
if msg.Command == "__ping" {
|
if msg.Command == "__ping" {
|
||||||
continue // generated by server, not by client
|
// generated for PONG packets
|
||||||
|
// want this to run AFTER lastPacket was set
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, char := range msg.Command {
|
for _, char := range msg.Command {
|
||||||
|
@ -510,14 +543,6 @@ func runSocketWriter(conn *websocket.Conn, client *ClientInfo, errorChan <-chan
|
||||||
}
|
}
|
||||||
SendMessage(conn, msg)
|
SendMessage(conn, msg)
|
||||||
|
|
||||||
case <-pingTicker.C:
|
|
||||||
now := time.Now()
|
|
||||||
if lastPacket.Add(5 * time.Minute).Before(now) {
|
|
||||||
return CloseTimedOut
|
|
||||||
} else if lastPacket.Add(1 * time.Minute).Before(now) {
|
|
||||||
conn.WriteControl(websocket.PingMessage, []byte(strconv.FormatInt(time.Now().Unix(), 10)), getDeadline())
|
|
||||||
}
|
|
||||||
|
|
||||||
case <-StopAcceptingConnectionsCh:
|
case <-StopAcceptingConnectionsCh:
|
||||||
return CloseGoingAway
|
return CloseGoingAway
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue