一,情景
因為golang.org/x/net/websocket未被go團隊納入標準庫,go團隊也未推薦使用,且次庫還有一些問題,並且不再維護。
所以,推薦使用:github.com/gorilla/websocket
安裝命令:
go get github.com/gorilla/websocket@latest
二, 服務端
package main
import (
"fmt"
"github.com/gorilla/websocket"
"log"
"net/http"
"net/url"
)
var UP websocket.Upgrader = websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
CheckOrigin: func(r *http.Request) bool { return true }, // 測試用,關閉跨域校驗
}
func handler(w http.ResponseWriter, r *http.Request) {
// ---- 解析查詢參數 ----
vals, err := url.ParseQuery(r.URL.RawQuery) // 或者 r.URL.Query()
if err != nil {
http.Error(w, "invalid query", http.StatusBadRequest)
return
}
cert := vals.Get("cert") // 拿到證書及其他參數
// ---- 業務:簡單校驗 ----
if cert == "" {
http.Error(w, "missing param cert", http.StatusBadRequest)
return
}
log.Printf("握手來自 %s, cert=%s", r.RemoteAddr, cert)
//升級處理
conn, err := UP.Upgrade(w, r, nil)
if err != nil {
log.Println(err)
return
}
defer conn.Close()
for {
messageType, p, e := conn.ReadMessage()
if e != nil {
log.Println(e)
break
}
fmt.Println(messageType, string(p))
conn.WriteMessage(messageType, []byte(cert+" : "+string(p)))
}
log.Println("服務關閉")
}
func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":9999", nil)
}
三, 客户端
package main
import (
"bufio"
"fmt"
"github.com/gorilla/websocket"
"os"
)
func main() {
dl := websocket.Dialer{}
conn, _, err := dl.Dial("ws://127.0.0.1:9999/?cert=kayer", nil)
if err != nil {
return
}
defer conn.Close()
conn.WriteMessage(websocket.BinaryMessage, []byte("hello world"))
go send(conn)
for {
m, p, e := conn.ReadMessage()
if e != nil {
break
}
fmt.Println(m, string(p))
}
}
func send(conn *websocket.Conn) {
for {
reader := bufio.NewReader(os.Stdin)
l, _, _ := reader.ReadLine()
conn.WriteMessage(websocket.BinaryMessage, l)
}
}