go-WebSocket编程
WebSocket是HTML5的重要特性,它实现了基于浏览器的远程socket,它使浏览器和服务器可以进行全双工通信。
在WebSocket出发之前,为了实现及时通信,采用的技术都是“轮询”,即在特定的时间间隔内,由浏览器对服务器发出HTTP Request,服务器在收到请求后,返回最新的数据给浏览器刷新,“轮询”使得浏览器需要对服务器不断发出请求,这样会占用大量的带宽。
WebSocket采用了一些特殊的报头,使得浏览器和服务器只需要做一个握手的动作,就可以在浏览器和服务器之间建立一条连接通道。且此连接会保持在活动状态,可以使用JavaScript来向连接写入或从中接收数据。相比传统的HTTP有如下好处:
- 一个Web客户端只建立一个TCP连接
- WebSocket服务端可以推送数据到web客户端
- 有更加轻量级的头,减少数据传输量
1.WebSocket客户端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| <!DOCTYPE html> <html lang="en">
<head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head>
<body> <h1>Websocket Test</h1> <form> <p> message: <input type="text" id="message" value="hello world!"> </p> </form> <button onclick="send();">Send Message</button> </body> <script type="text/javascript"> var sock = null; var wsuri = "ws://127.0.0.1:8080";
window.onload = function () { console.log("onload"); sock = new WebSocket(wsuri);
sock.onopen = function () { console.log("connected to " + wsuri) };
sock.onclose = function (e) { console.log("connection closed (" + e.code + ")") };
sock.onmessage = function (e) { console.log("message received: " + e.data) }; };
function send() { var msg = document.getElementById('message').value; sock.send(msg) } </script>
</html>
|
2.WebSocket服务端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| package main
import ( "log" "net/http"
"github.com/gorilla/websocket" )
func main() { http.HandleFunc("/", handleWS) http.ListenAndServe(":8080", nil) }
var upgrader = websocket.Upgrader{ ReadBufferSize: 1024, WriteBufferSize: 1024, CheckOrigin: func(r *http.Request) bool { return true }, }
func handleWS(w http.ResponseWriter, r *http.Request) { conn, err := upgrader.Upgrade(w, r, nil) if err != nil { log.Fatal(err) return } defer conn.Close()
for { messageType, data, err := conn.ReadMessage() if err != nil { log.Fatal(err) return }
resp := []byte("recive data, and the data is " + string(data)) err = conn.WriteMessage(messageType, resp) if err != nil { log.Fatal(err) return } } }
|