無論是在線聊天、多人遊戲、即時通知還是實時數據更新,都需要一個高效的方式來實現實時通信。Golang,提供了一個強大的工具來實現這種功能 - WebSocket。
WebSocket
是一種在 瀏覽器
和 伺服器
之間實現 全雙工
通信的協議,允許在 不重新載入
頁面的情況下,客戶端
和伺服器
之間持續地傳遞
數據。在 Golang 中,可以使用 gorilla/websocket 套件來實現 WebSocket 通信。
server 端
這個伺服器創建一個 WebSocket 伺服器,並在 /ws 路由上等待客戶端連接。當客戶端連接後,伺服器將持續地接收來自客戶端的消息,然後將它們返回給客戶端。
package main
import (
"fmt"
"net/http"
"github.com/gorilla/websocket"
)
var upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
}
func handleConnection(w http.ResponseWriter, r *http.Request) {
// 升級HTTP連接為WebSocket連接
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
fmt.Println(err)
return
}
defer conn.Close()
for {
// 讀取客戶端發送的消息
messageType, p, err := conn.ReadMessage()
if err != nil {
fmt.Println(err)
return
}
// 將消息回傳給客戶端
if err := conn.WriteMessage(messageType, p); err != nil {
fmt.Println(err)
return
}
}
}
func main() {
http.HandleFunc("/ws", handleConnection)
fmt.Println("WebSocket 伺服器運行在 :8080 端口")
http.ListenAndServe(":8080", nil)
}
client 端
這個客戶端連接到我們剛剛創建的 WebSocket 伺服器,並持續地接收來自伺服器的消息。還處理了中斷信號,以確保在結束之前正確關閉連接。
package main
import (
"fmt"
"github.com/gorilla/websocket"
"os"
"os/signal"
"time"
)
func main() {
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt)
u := fmt.Sprintf("ws://localhost:8080/ws")
fmt.Println("正在連接到", u)
c, _, err := websocket.DefaultDialer.Dial(u, nil)
if err != nil {
fmt.Println("連接失敗:", err)
return
}
defer c.Close()
done := make(chan struct{})
go func() {
defer close(done)
for {
_, message, err := c.ReadMessage()
if err != nil {
fmt.Println("接收消息失敗:", err)
return
}
fmt.Printf("接收到消息: %s\n", message)
}
}()
for {
select {
case <-done:
return
case <-interrupt:
fmt.Println("接收到中斷信號,關閉連接...")
err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
if err != nil {
fmt.Println("關閉連接失敗:", err)
return
}
select {
case <-done:
case <-time.After(time.Second):
}
return
}
}
}
長輩都說,中秋過後每下一次雨,溫度都會下降一些,不知道這次颱風來下降的溫度還會不會回升?