近期在用GoFrame框架使用websocket时根据官方给出的案例创建websocket
golang 服务端
package main
import (
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/net/ghttp"
"github.com/gogf/gf/os/gfile"
"github.com/gogf/gf/os/glog"
)
func main() {
s := g.Server()
s.BindHandler("/ws", func(r *ghttp.Request) {
ws, err := r.WebSocket()
if err != nil {
glog.Error(err)
r.Exit()
}
for {
msgType, msg, err := ws.ReadMessage()
if err != nil {
return
}
if err = ws.WriteMessage(msgType, msg); err != nil {
return
}
}
})
s.SetServerRoot(gfile.MainPkgPath())
s.SetPort(8199)
s.Run()
}
客户端
$(function () {
var url = "ws://127.0.0.1:8199/ws";
var ws = new WebSocket(url);
try {
// ws连接成功
ws.onopen = function () {
showInfo("WebSocket Server [" + url +"] 连接成功!");
};
// ws连接关闭
ws.onclose = function () {
if (ws) {
ws.close();
ws = null;
}
showError("WebSocket Server [" + url +"] 连接关闭!");
};
// ws连接错误
ws.onerror = function () {
if (ws) {
ws.close();
ws = null;
}
showError("WebSocket Server [" + url +"] 连接关闭!");
};
// ws数据返回处理
ws.onmessage = function (result) {
showWaring(" > " + result.data);
};
} catch (e) {
alert(e.message);
}
})
可以正常连接成功,但在使用token后报错:
var url = "ws://127.0.0.1:8199/ws";
var token = "tokentest"
var ws = new WebSocket(url, token);
报错信息:
WebSocket connection to 'ws://127.0.0.1:8199/ws' failed: Error during WebSocket handshake: Sent non-empty 'Sec-WebSocket-Protocol' header but no response was received
查看请求头发现,请求头中多出了 Sec-WebSocket-Protocol 来记录token。
服务端需要对请求头中的 Sec-WebSocket-Protocol 进行特殊处理。
修改服务端websocket创建代码:
package main
import (
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/net/ghttp"
"github.com/gogf/gf/os/gfile"
"github.com/gogf/gf/os/glog"
"github.com/gogf/gf/third/github.com/gorilla/websocket"
"net/http"
)
func main() {
s := g.Server()
s.BindHandler("/ws", func(r *ghttp.Request) {
upgrade := &websocket.Upgrader{
// 检测请求来源
CheckOrigin: func(r *http.Request) bool {
return true
},
Subprotocols:[]string{r.Request.Header.Get("Sec-WebSocket-Protocol")},
}
responseWriter := r.Response.ResponseWriter.ResponseWriter
ws, err := upgrade.Upgrade(responseWriter, r.Request, nil)
if err != nil {
glog.Error(err)
r.Exit()
}
for {
msgType, msg, err := ws.ReadMessage()
if err != nil {
return
}
if err = ws.WriteMessage(msgType, msg); err != nil {
return
}
}
})
s.SetServerRoot(gfile.MainPkgPath())
s.SetPort(8199)
s.Run()
}
成功!