1.需要的websocket的包:
"github.com/gorilla/websocket"
package main import ( "github.com/gorilla/websocket" "learngo/websocket/impl" "net/http" "time" ) var( upgrader = websocket.Upgrader{ //允许跨域访问 CheckOrigin: func(r *http.Request) bool { return true }, } ) func wsHandler(w http.ResponseWriter, r *http.Request) { //w.Write([]byte("hello")) //收到http请求(upgrade),完成websocket协议转换 //在应答的header中放上upgrade:websoket var ( wsConn *websocket.Conn err error data []byte conn *impl.Connection ) //Upgrade websocket(返回给客户端的消息) if wsConn, err = upgrader.Upgrade(w, r, nil); err !=nil { //报错了,直接返回底层的websocket链接就会终断掉 return } if conn, err = impl.InitConnection(wsConn); err != nil { goto ERR } //心跳 go func() { var( err error ) for { if err = conn.WriteMessage([]byte("heatbeat")); err != nil { return } time.Sleep(5*time.Second) } }() for { if data, err = conn.ReadMessage(); err != nil { goto ERR } if err = conn.WriteMessage(data); err != nil { goto ERR } } ERR: conn.Close() } func userHandler(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Hello World!")) } func main() { //http://localhost:7777/ws http.HandleFunc("/ws", wsHandler) http.HandleFunc("/user", userHandler) //服务端启动 http.ListenAndServe("0.0.0.0:7777", nil) }
实现模块:线程安全
package main import ( "github.com/gorilla/websocket" "net/http" ) var( upgrader = websocket.Upgrader{ //允许跨域访问 CheckOrigin: func(r *http.Request) bool { return true }, } ) func wsHandler(w http.ResponseWriter, r *http.Request) { //w.Write([]byte("hello")) //收到http请求(upgrade),完成websocket协议转换 //在应答的header中放上upgrade:websoket var ( conn *websocket.Conn err error //msgType int data []byte ) if conn, err = upgrader.Upgrade(w, r, nil); err !=nil { //报错了,直接返回底层的websocket链接就会终断掉 return } //得到了websocket.Conn长连接的对象,实现数据的收发 for { //Text(json), Binary //if _, data, err = conn.ReadMessage(); err != nil { if _, data, err = conn.ReadMessage(); err != nil { //报错关闭websocket goto ERR } //发送数据,判断返回值是否报错 if err = conn.WriteMessage(websocket.TextMessage, data); err != nil { //报错了 goto ERR } } //error的标签 ERR: conn.Close() } func helloHandler(w http.ResponseWriter, r *http.Request){ w.Write([]byte("Hello World!")) } func main() { //http://localhost:7777/ws http.HandleFunc("/ws", wsHandler) http.HandleFunc("/hello", helloHandler) //服务端启动 http.ListenAndServe("0.0.0.0:7777", nil) }
js文件:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script> window.addEventListener("load", function(evt) { var output = document.getElementById("output"); var input = document.getElementById("input"); var ws; var print = function(message) { var d = document.createElement("div"); d.innerHTML = message; output.appendChild(d); }; document.getElementById("open").onclick = function(evt) { if (ws) { return false; } ws = new WebSocket("ws://192.168.230.130:7777/ws"); ws.onopen = function(evt) { print("OPEN"); } ws.onclose = function(evt) { print("CLOSE"); ws = null; } ws.onmessage = function(evt) { print("RESPONSE: " + evt.data); } ws.onerror = function(evt) { print("ERROR: " + evt.data); } return false; }; document.getElementById("send").onclick = function(evt) { if (!ws) { return false; } print("SEND: " + input.value); ws.send(input.value); return false; }; document.getElementById("close").onclick = function(evt) { if (!ws) { return false; } ws.close(); return false; }; }); </script> </head> <body> <table> <tr><td valign="top" width="50%"> <p>Click "Open" to create a connection to the server, "Send" to send a message to the server and "Close" to close the connection. You can change the message and send multiple times. </p> <form> <button id="open">Open</button> <button id="close">Close</button> <input id="input" type="text" value="Hello world!"> <button id="send">Send</button> </form> </td><td valign="top" width="50%"> <div id="output"></div> </td></tr></table> </body> </html>