Go每日一库之100:websocket

2023-09-30 08:32:00 浏览数 (2)

Go语言标准包里面没有提供对WebSocket的支持,但是在由官方维护的go.net子包中有对这个的支持,需要独立下载。

Go websocket package 下载地址: http://code.google.com/p/go.net/websocket

Go get 命令下载: go get code.google.com/p/go.net/websocket

Go实现的WebSocket的文档: http://godoc.org/code.google.com/p/go.net/websocket

WebSocket官网提供了一个webSocket测试地址: http://www.websocket.org/echo.html 在这里输入 websocket的地址就可以进行测试。

Go服务器端源码:

代码语言:javascript复制
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() {
    fmt.Println("begin")
    http.Handle("/", http.FileServer(http.Dir("."))) // <-- note this line
    http.Handle("/socket", websocket.Handler(Echo))
    if err := http.ListenAndServe(":1234", nil); err != nil {
        log.Fatal("ListenAndServe:", err)
    }

    fmt.Println("end")
}

测试的网页:

代码语言:javascript复制
<!DOCTYPE html>  

<meta charset="utf-8" />  

<title>WebSocket Test</title>  

<script language="javascript"type="text/javascript">  

 

var wsUri ="ws://localhost:1234/socket"; 

//var wsUri = "ws://localhost/socket"; 

//var wsUri = "ws://echo.websocket.org"; 

var output;  

function init() { 

    output = document.getElementById("output"); 

    testWebSocket(); 

}  

function testWebSocket() { websocket = new WebSocket(wsUri); 

    websocket.onopen = function(evt) { onOpen(evt) }; 

    websocket.onclose = function(evt) { onClose(evt) }; 

    websocket.onmessage = function(evt) { onMessage(evt) }; 

    websocket.onerror = function(evt) { onError(evt) }; }  

 

  function onOpen(evt) { writeToScreen("CONNECTED"); doSend("WebSocket rocks"); }  
  function onClose(evt) { 

        writeToScreen("DISCONNECTED"); }  

 
    function onMessage(evt) { 

        writeToScreen('<span style="color: blue;">RESPONSE: '  evt.data '</span>'); 

        websocket.close(); }  

    function onError(evt) { 

        writeToScreen('<span style="color: red;">ERROR:</span> '  evt.data); }  


    function doSend(message) { 

        writeToScreen("SENT: "   message);  

        websocket.send(message); }  

    function writeToScreen(message) { 

        var pre = document.createElement("p"); 

        pre.style.wordWrap = "break-word"; 

        pre.innerHTML = message; output.appendChild(pre); }


    window.addEventListener("load", init, false);  

</script>



  <h2>WebSocket Test</h2>  

  <div id="output"></div>  

  </html>

注意,测试时候 测试html网页是需要在 http://localhost:1234/test.html 这样的地址进行测试。 如果用 file://localhost/Users/cybercare/go/src/websocket/test.html 测试会报错误。 Chrome浏览器可能会抛出400错误,是因为它认为你正在尝试做一个跨域请求WebSocket。即它认为你没有跨域请求的权限。You should host your html javascript on http:// (or https://), not file://

Static html page created the WebSocket connection golang server directly http://stackoverflow.com/questions/15884480/static-html-page-created-the-websocket-connection-golang-server-directly

Go websocket server not working with browser https://groups.google.com/forum/?fromgroups=#!topic/golang-nuts/pNYy5brIF6E

不过如果使用 file://localhost/Users/cybercare/go/src/websocket/test.html 访问访问 var wsUri = "ws://echo.websocket.org"; 则不会有任何问题,而访问 var wsUri = "ws://localhost:1234/socket"; 就会报上面错误:

使用

打开 chrome://net-internals/#events, 输入ws进行过滤,其中的 SOCKET_STREAM 信息如下: 下面是本地静态文件请求 ws://echo.websocket.org/ 的信息截屏。 Websockets?https://groups.google.com/forum/?fromgroups=#!topic/golang-nuts/2QwiBb7ZgrA 本地静态文件请求 ws://localhost:1234/socket 提示错误: HTTP/1.1 400 Bad Request 的信息监控。

这是因为 我们用的这个 websocket 框架 在处理请求的 Origin 时,把它当URL来处理,而本地静态文件发送上来的Origin是null。这里解析错误就会报400错误。 go 官方的这个Orgin解析代码我们可以在下面地址看到(536行): https://code.google.com/p/go/source/browse/websocket/hixie.go?repo=net#536

https://code.google.com/p/go/source/browse/websocket/server.go?spec=svn.net.9c2295dac419afbe918298a9c90f49786819b569&repo=net&r=2513e900821392c12653a526c6e36a2d3db4da5c#28

参考资料

go-websocket-sample https://github.com/ukai/go-websocket-sample Can't connect to Server through Chrome. https://code.google.com/p/go/issues/detail?id=3987 Go WebSocket开发 http://www.cnblogs.com/yjf512/archive/2013/02/18/2915171.html 8.2 WebSocket https://github.com/astaxie/build-web-application-with-golang/blob/master/ebook/08.2.md 广泛意思上的websocket包 http://bbs.mygolang.com/thread-330-1-1.html golang websocket总结(问题贴) http://blog.csdn.net/lxy15329/article/details/8737912 基于Golang的WebSocket Server http://www.xinze.me/基于golang的websocket-server/

0 人点赞