WebSocket Ping Pong中文通常又稱為心跳(heartbeat),是指WebSocket協議的控制碼(opcode),代表Control frame(控制幀/控制框)的Ping frame與Pong frame,用以偵測客戶端和伺服器間的連線是否存在,以實現長連線(Keep-Alive)的機制。參考RFC6455。
事前要求
參考「Golang WebSocket hello world」了解gorilla/websocket
實現WebSocket的做法。
範例
下面範例的ping()
函式中透過定時器time.Ticker
,定時使用websocket.Conn.WriteMessage
寫出一個Ping訊息並夾帶"ping"字串的payload(又稱Application data)到客戶端(瀏覽器)。
有實作WebSocket協議Ping Pong的客戶端(例如Chrome瀏覽器)在收到Ping訊息後,會立刻回應一個Pong訊息並把Ping payload一樣的內容回送給伺服端。handlePong()
函式中,使用websocket.Conn.SetPongHandler
設定一個處理Pong訊息的函式。
read()
函式中使用一個for無窮迴圈中呼叫Conn.ReadMessage
持續讀取client送來的訊息。
main.go
package main
import (
"fmt"
"net/http"
"time"
"github.com/gorilla/websocket"
)
var upgrader = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
return true // allow CORS request's Origin header
},
}
func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
}
// websocket handler
func handler(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil) // upgrade to a websocket connection
if err != nil {
panic(err)
}
go ping(conn)
handlePong(conn)
read(conn)
}
const (
PING = "ping"
PONG = "pong"
pongWait = 5 * time.Second
pingPeriod = pongWait - 1
)
func ping(conn *websocket.Conn) {
ticker := time.NewTicker(pingPeriod)
defer func() {
ticker.Stop()
conn.Close()
}()
fmt.Println("websocket connection openned")
for range ticker.C {
err := conn.WriteMessage(websocket.PingMessage, []byte(PING))
if err != nil {
return
}
}
}
func handlePong(conn *websocket.Conn) {
conn.SetPongHandler(func(appData string) error {
if appData == PING {
fmt.Println(PONG)
}
return nil
})
}
func read(conn *websocket.Conn) {
defer func() {
conn.Close()
fmt.Println("websocket connection closed")
}()
for {
_, message, err := conn.ReadMessage() // read message from client
if err != nil {
if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway) {
fmt.Printf("error: %v", err)
}
break
}
fmt.Printf("receive: %s\n", message)
}
}
測試
啟動Go應用程式,Chrome瀏覽器安裝Simple WebSocket Client並打開。在[Server Location]的[URL]欄位輸入ws://localhost:8080/
然後按Open開啟WebSocket連線,然後觀察Go應用程式會每5秒印出"pong"直到連線關閉(例如關閉Simple WebSocket Client分頁)。
websocket connection openned
pong
pong
...
websocket connection closed
沒有留言:
張貼留言