在 Go 語言中使用 Websocket
前言
先前在網頁中想取得即時資料。在那個時候有聽到 websocket 這個東西,但一直沒有時間試試。最近剛好又想起了這件事,於是乎這一篇就誕生啦。
本篇會透過一個簡單的範例 echo
來練習使用 WebSocket。
主要內容
Websocket 是基於 HTTP/HTTPS 協定,後續再使用 Upgrade Header 改為 WebSocket 協定。
來個簡單的範例吧
這個範例會實做 2 個部份,一個是使用 Go 語言實作的網頁後端服務,它會提供 WebSocket 伺服端;另一個部份是使用 HTML + Javascript 實作客戶端的部份。
網頁後端
這個範例我們使用的是 gorilla/websocket 實作的版本,我們可以透過下例的指令來使用它。
1go get github.com/gorilla/websocket
echo
函式中會使用 Upgrader 將目前使用的協定從 http 協定改為 WebSocket ,並開始接收來自客戶端的訊息。當收到訊息後,會直接把收到的訊息直接回傳給客戶端。
main.go
1package main
2
3import (
4 "log"
5 "net/http"
6
7 "github.com/gorilla/websocket"
8)
9
10var upgrader = websocket.Upgrader{
11 CheckOrigin: func(r *http.Request) bool {return true},
12}
13
14// 提供 echo 服務
15func echo(w http.ResponseWriter, r *http.Request){
16 c, err := upgrader.Upgrade(w, r, nil)
17 if err != nil {
18 log.Print("upgrade:", err)
19 return
20 }
21 defer c.Close()
22 for {
23 // 接收到的訊息
24 messageType, message, err := c.ReadMessage()
25 if err != nil {
26 log.Println("read:", err)
27 break
28 }
29 log.Println("read", string(message))
30 // 送出原本收到的訊息
31 err = c.WriteMessage(messageType, message)
32 if err != nil {
33 log.Println("write:", err)
34 break
35 }
36 log.Println("send", string(message))
37 }
38}
39
40func main(){
41 http.HandleFunc("/ws", echo)
42 http.ListenAndServe(":8080", nil)
43}
網頁前端
index.html
1<!DOCTYPE html>
2<html lang="en">
3<head>
4 <meta charset="UTF-8">
5 <meta http-equiv="X-UA-Compatible" content="IE=edge">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0">
7 <script>
8 // 載入完成
9 window.addEventListener("load", function (event) {
10 msg = document.getElementById("msg");
11 btn = document.getElementById("btn");
12 input = document.getElementById("input");
13
14 // 加上按鈕按下時的處理函式
15 btn.addEventListener("click", event => {
16 console.log("fire~", input.value)
17 ws.send(input.value)
18 })
19
20 // 建立 websocket 連線
21 let ws = new WebSocket("ws://localhost:8080/ws");
22 ws.onopen = () => {
23 console.log("ws is open");
24 }
25
26 ws.onclose = () => {
27 console.log("ws is close");
28 }
29
30 // 加上收到訊息時的處理函式 - 將收到的訊息顯示在 msg 中。
31 ws.onmessage = event => {
32 msg.innerHTML = event.data
33 console.log("roger~~", event.data)
34 }
35
36 window.addEventListener("beforeunload", function (event) {
37 ws.close()
38 })
39
40 });
41 </script>
42 <title>WebSocket 測試 - ECHO</title>
43</head>
44<body>
45 <div>
46 <div>收到的訊息</div>
47 <div id="msg"></div>
48 </div>
49 <input type="text" id="input" /><button id="btn">send</button>
50 </body>
51</html>
結果
當我們輸入 hi
並按下 send 時後端會收到我們所傳送的訊息,並立即回傳給前端。

範例執行結果
小結
本文撰寫了一個非常簡單的範例,主要的目的在於瞭解 WebSocket 的使用方式。實際在使用時,還會有其他的業務邏輯與異常處理的部份。有興趣的同學就再自行玩玩囉~