mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
Add Ping Timeout Signal for WebSocket Client (#8666)
Import Order gofmt gofmt gofmt Renamed Const to make Unit more obvious Renamed Const to make Unit more obvious #2
This commit is contained in:
committed by
Joram Wilander
parent
d8dd271e43
commit
7fa1c6c4ba
@@ -6,24 +6,28 @@ package model
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
)
|
||||
|
||||
const (
|
||||
SOCKET_MAX_MESSAGE_SIZE_KB = 8 * 1024 // 8KB
|
||||
SOCKET_MAX_MESSAGE_SIZE_KB = 8 * 1024 // 8KB
|
||||
PING_TIMEOUT_BUFFER_SECONDS = 5
|
||||
)
|
||||
|
||||
type WebSocketClient struct {
|
||||
Url string // The location of the server like "ws://localhost:8065"
|
||||
ApiUrl string // The api location of the server like "ws://localhost:8065/api/v3"
|
||||
ConnectUrl string // The websocket URL to connect to like "ws://localhost:8065/api/v3/path/to/websocket"
|
||||
Conn *websocket.Conn // The WebSocket connection
|
||||
AuthToken string // The token used to open the WebSocket
|
||||
Sequence int64 // The ever-incrementing sequence attached to each WebSocket action
|
||||
EventChannel chan *WebSocketEvent
|
||||
ResponseChannel chan *WebSocketResponse
|
||||
ListenError *AppError
|
||||
Url string // The location of the server like "ws://localhost:8065"
|
||||
ApiUrl string // The api location of the server like "ws://localhost:8065/api/v3"
|
||||
ConnectUrl string // The websocket URL to connect to like "ws://localhost:8065/api/v3/path/to/websocket"
|
||||
Conn *websocket.Conn // The WebSocket connection
|
||||
AuthToken string // The token used to open the WebSocket
|
||||
Sequence int64 // The ever-incrementing sequence attached to each WebSocket action
|
||||
PingTimeoutChannel chan bool // The channel used to signal ping timeouts
|
||||
EventChannel chan *WebSocketEvent
|
||||
ResponseChannel chan *WebSocketResponse
|
||||
ListenError *AppError
|
||||
pingTimeoutTimer *time.Timer
|
||||
}
|
||||
|
||||
// NewWebSocketClient constructs a new WebSocket client with convenience
|
||||
@@ -47,11 +51,15 @@ func NewWebSocketClientWithDialer(dialer *websocket.Dialer, url, authToken strin
|
||||
conn,
|
||||
authToken,
|
||||
1,
|
||||
make(chan bool, 1),
|
||||
make(chan *WebSocketEvent, 100),
|
||||
make(chan *WebSocketResponse, 100),
|
||||
nil,
|
||||
nil,
|
||||
}
|
||||
|
||||
client.configurePingHandling()
|
||||
|
||||
client.SendMessage(WEBSOCKET_AUTHENTICATION_CHALLENGE, map[string]interface{}{"token": authToken})
|
||||
|
||||
return client, nil
|
||||
@@ -78,11 +86,15 @@ func NewWebSocketClient4WithDialer(dialer *websocket.Dialer, url, authToken stri
|
||||
conn,
|
||||
authToken,
|
||||
1,
|
||||
make(chan bool, 1),
|
||||
make(chan *WebSocketEvent, 100),
|
||||
make(chan *WebSocketResponse, 100),
|
||||
nil,
|
||||
nil,
|
||||
}
|
||||
|
||||
client.configurePingHandling()
|
||||
|
||||
client.SendMessage(WEBSOCKET_AUTHENTICATION_CHALLENGE, map[string]interface{}{"token": authToken})
|
||||
|
||||
return client, nil
|
||||
@@ -99,6 +111,8 @@ func (wsc *WebSocketClient) ConnectWithDialer(dialer *websocket.Dialer) *AppErro
|
||||
return NewAppError("Connect", "model.websocket_client.connect_fail.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
wsc.configurePingHandling()
|
||||
|
||||
wsc.EventChannel = make(chan *WebSocketEvent, 100)
|
||||
wsc.ResponseChannel = make(chan *WebSocketResponse, 100)
|
||||
|
||||
@@ -181,3 +195,24 @@ func (wsc *WebSocketClient) GetStatusesByIds(userIds []string) {
|
||||
}
|
||||
wsc.SendMessage("get_statuses_by_ids", data)
|
||||
}
|
||||
|
||||
func (wsc *WebSocketClient) configurePingHandling() {
|
||||
wsc.Conn.SetPingHandler(wsc.pingHandler)
|
||||
wsc.pingTimeoutTimer = time.NewTimer(time.Second * (60 + PING_TIMEOUT_BUFFER_SECONDS))
|
||||
go wsc.pingWatchdog()
|
||||
}
|
||||
|
||||
func (wsc *WebSocketClient) pingHandler(appData string) error {
|
||||
if !wsc.pingTimeoutTimer.Stop() {
|
||||
<-wsc.pingTimeoutTimer.C
|
||||
}
|
||||
|
||||
wsc.pingTimeoutTimer.Reset(time.Second * (60 + PING_TIMEOUT_BUFFER_SECONDS))
|
||||
wsc.Conn.WriteMessage(websocket.PongMessage, []byte{})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (wsc *WebSocketClient) pingWatchdog() {
|
||||
<-wsc.pingTimeoutTimer.C
|
||||
wsc.PingTimeoutChannel <- true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user