在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ GO/ 8.2 WebSocket
7 文本處理
3 Web基礎
14 擴展Web框架
10.4 小結
2.2 Go基礎
2.8 總結
6.1 session和cookie
5.5 使用beedb庫進行ORM開發(fā)
8.3 REST
13.6 小結
5.4 使用PostgreSQL數據庫
14.6 pprof支持
14.1 靜態(tài)文件支持
11.2 使用GDB調試
7.7 小結
1 GO環(huán)境配置
14.5 多語言支持
7.1 XML處理
1.5 總結
13 如何設計一個Web框架
14.3 表單及驗證支持
12 部署與維護
10 國際化和本地化
1.1 Go 安裝
6.2 Go如何使用session
5.6 NOSQL數據庫操作
6.5 小結
9.4 避免SQL注入
12.1 應用日志
4.2 驗證表單的輸入
10.1 設置默認地區(qū)
1.3 Go 命令
9.6 加密和解密數據
4.1 處理表單的輸入
4.4 防止多次遞交表單
11.3 Go怎么寫測試用例
8 Web服務
12.3 應用部署
5.7 小結
12.5 小結
11 錯誤處理,調試和測試
9.2 確保輸入過濾
14.2 Session支持
6.4 預防session劫持
12.4 備份和恢復
8.1 Socket編程
13.1 項目規(guī)劃
13.4 日志和配置設計
7.6 字符串處理
13.2 自定義路由器設計
6.3 session存儲
3.4 Go的http包詳解
8.2 WebSocket
10.3 國際化站點
7.5 文件操作
7.4 模板處理
9.1 預防CSRF攻擊
13.3 controller設計
2.6 interface
14.4 用戶認證
2.3 流程和函數
附錄A 參考資料
11.1 錯誤處理
9.5 存儲密碼
9.3 避免XSS攻擊
12.2 網站錯誤處理
6 session和數據存儲
2.4 struct類型
3.3 Go如何使得Web工作
2.5 面向對象
3.1 Web工作方式
1.2 GOPATH與工作空間
2.1 你好,Go
9.7 小結
13.5 實現(xiàn)博客的增刪改
7.2 JSON處理
10.2 本地化資源
7.3 正則處理
2 Go語言基礎
5.1 database/sql接口
4.5 處理文件上傳
8.5 小結
4.3 預防跨站腳本
5.3 使用SQLite數據庫
14.7 小結
3.2 Go搭建一個Web服務器
2.7 并發(fā)
5 訪問數據庫
4 表單
3.5 小結
1.4 Go開發(fā)工具
11.4 小結
9 安全與加密
5.2 使用MySQL數據庫
4.6 小結
8.4 RPC

8.2 WebSocket

WebSocket是HTML5的重要特性,它實現(xiàn)了基于瀏覽器的遠程socket,它使瀏覽器和服務器可以進行全雙工通信,許多瀏覽器(Firefox、Google Chrome和Safari)都已對此做了支持。

在WebSocket出現(xiàn)之前,為了實現(xiàn)即時通信,采用的技術都是“輪詢”,即在特定的時間間隔內,由瀏覽器對服務器發(fā)出HTTP Request,服務器在收到請求后,返回最新的數據給瀏覽器刷新,“輪詢”使得瀏覽器需要對服務器不斷發(fā)出請求,這樣會占用大量帶寬。

WebSocket采用了一些特殊的報頭,使得瀏覽器和服務器只需要做一個握手的動作,就可以在瀏覽器和服務器之間建立一條連接通道。且此連接會保持在活動狀態(tài),你可以使用JavaScript來向連接寫入或從中接收數據,就像在使用一個常規(guī)的TCP Socket一樣。它解決了Web實時化的問題,相比傳統(tǒng)HTTP有如下好處:

  • 一個Web客戶端只建立一個TCP連接
  • Websocket服務端可以推送(push)數據到web客戶端.
  • 有更加輕量級的頭,減少數據傳送量

WebSocket URL的起始輸入是ws://或是wss://(在SSL上)。下圖展示了WebSocket的通信過程,一個帶有特定報頭的HTTP握手被發(fā)送到了服務器端,接著在服務器端或是客戶端就可以通過JavaScript來使用某種套接口(socket),這一套接口可被用來通過事件句柄異步地接收數據。

http://wiki.jikexueyuan.com/project/go-web-programming/images/8.2.websocket.png" alt="" />

圖8.2 WebSocket原理圖

WebSocket原理

WebSocket的協(xié)議頗為簡單,在第一次handshake通過以后,連接便建立成功,其后的通訊數據都是以”\x00″開頭,以”\xFF”結尾。在客戶端,這個是透明的,WebSocket組件會自動將原始數據“掐頭去尾”。

瀏覽器發(fā)出WebSocket連接請求,然后服務器發(fā)出回應,然后連接建立成功,這個過程通常稱為“握手” (handshaking)。請看下面的請求和反饋信息:

http://wiki.jikexueyuan.com/project/go-web-programming/images/8.2.websocket2.png" alt="" />

圖8.3 WebSocket的request和response信息

在請求中的"Sec-WebSocket-Key"是隨機的,對于整天跟編碼打交到的程序員,一眼就可以看出來:這個是一個經過base64編碼后的數據。服務器端接收到這個請求之后需要把這個字符串連接上一個固定的字符串:

258EAFA5-E914-47DA-95CA-C5AB0DC85B11

即:f7cb4ezEAl6C3wRaU6JORA==連接上那一串固定字符串,生成一個這樣的字符串:

f7cb4ezEAl6C3wRaU6JORA==258EAFA5-E914-47DA-95CA-C5AB0DC85B11

對該字符串先用 sha1安全散列算法計算出二進制的值,然后用base64對其進行編碼,即可以得到握手后的字符串:

rE91AJhfC+6JdVcVXOGJEADEJdQ=

將之作為響應頭Sec-WebSocket-Accept的值反饋給客戶端。

Go實現(xiàn)WebSocket

Go語言標準包里面沒有提供對WebSocket的支持,但是在由官方維護的go.net子包中有對這個的支持,你可以通過如下的命令獲取該包:

go get code.google.com/p/go.net/websocket

WebSocket分為客戶端和服務端,接下來我們將實現(xiàn)一個簡單的例子:用戶輸入信息,客戶端通過WebSocket將信息發(fā)送給服務器端,服務器端收到信息之后主動Push信息到客戶端,然后客戶端將輸出其收到的信息,客戶端的代碼如下:

<html>
<head></head>
<body>
    <script type="text/javascript">
        var sock = null;
        var wsuri = "ws://127.0.0.1:1234";

        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>
    <h1>WebSocket Echo Test</h1>
    <form>
        <p>
            Message: <input id="message" type="text" value="Hello, world!">
        </p>
    </form>
    <button onclick="send();">Send Message</button>
</body>
</html>

可以看到客戶端JS,很容易的就通過WebSocket函數建立了一個與服務器的連接sock,當握手成功后,會觸發(fā)WebScoket對象的onopen事件,告訴客戶端連接已經成功建立??蛻舳艘还步壎怂膫€事件。

  • 1)onopen 建立連接后觸發(fā)
  • 2)onmessage 收到消息后觸發(fā)
  • 3)onerror 發(fā)生錯誤時觸發(fā)
  • 4)onclose 關閉連接時觸發(fā)

我們服務器端的實現(xiàn)如下:

package main

import (
    "code.google.com/p/go.net/websocket"
    "fmt"
    "log"
    "net/http"
)

func Echo(ws *websocket.Conn) {
    var err error

    for {
        var reply string

        if err = websocket.Message.Receive(ws, &reply); err != nil {
            fmt.Println("Can't receive")
            break
        }

        fmt.Println("Received back from client: " + reply)

        msg := "Received:  " + reply
        fmt.Println("Sending to client: " + msg)

        if err = websocket.Message.Send(ws, msg); err != nil {
            fmt.Println("Can't send")
            break
        }
    }
}

func main() {
    http.Handle("/", websocket.Handler(Echo))

    if err := http.ListenAndServe(":1234", nil); err != nil {
        log.Fatal("ListenAndServe:", err)
    }
}

當客戶端將用戶輸入的信息Send之后,服務器端通過Receive接收到了相應信息,然后通過Send發(fā)送了應答信息。

http://wiki.jikexueyuan.com/project/go-web-programming/images/8.2.websocket3.png" alt="" />

圖8.4 WebSocket服務器端接收到的信息

通過上面的例子我們看到客戶端和服務器端實現(xiàn)WebSocket非常的方便,Go的源碼net分支中已經實現(xiàn)了這個的協(xié)議,我們可以直接拿來用,目前隨著HTML5的發(fā)展,我想未來WebSocket會是Web開發(fā)的一個重點,我們需要儲備這方面的知識。

上一篇:8 Web服務下一篇:9 安全與加密