GO 語言websocket編程__websocket

來源:互聯網
上載者:User

GO提供原生的websocket API,使用時go get然後引用即可
golang.org/x/net/websocket
使用起來也很方便,直接上代碼吧。 一個echo server的代碼

package mainimport(    "golang.org/x/net/websocket"    "fmt"    "net/http"    "flag")type WSServer struct {    ListenAddr string}func (this *WSServer)handler(conn *websocket.Conn){    fmt.Printf("a new ws conn: %s->%s\n", conn.RemoteAddr().String(), conn.LocalAddr().String())    var err error    for {        var reply string        err = websocket.Message.Receive(conn, &reply)        if err != nil {            fmt.Println("receive err:",err.Error())            break        }        fmt.Println("Received from client: " + reply)        if err = websocket.Message.Send(conn, reply); err != nil {            fmt.Println("send err:", err.Error())            break        }    }}func (this *WSServer)start()(error){    http.Handle("/ws", websocket.Handler(this.handler))    fmt.Println("begin to listen")    err := http.ListenAndServe(this.ListenAddr, nil)    if err != nil {        fmt.Println("ListenAndServe:", err)        return err    }    fmt.Println("start end")    return nil}func main(){    addr  := flag.String("a", "127.0.1.1:12345", "websocket server listen address")    flag.Parse()    wsServer := &WSServer{        ListenAddr : *addr,    }    wsServer.start()    fmt.Println("------end-------")}

上述代碼中,每來一個新的websocket client,server會起一個goroutine執行WSSever的handler函數。 websocket client代碼執行個體

package mainimport (    "flag"    "fmt"    "time"    "golang.org/x/net/websocket")var addr = flag.String("addr", "127.0.0.1:12345", "http service address")func main() {    flag.Parse()    url := "ws://"+ *addr + "/ws"    origin := "test://1111111/"    ws, err := websocket.Dial(url, "", origin)    if err != nil {        fmt.Println(err)    }    go timeWriter(ws)    for {        var msg [512]byte        _, err := ws.Read(msg[:])//此處阻塞,等待有資料可讀        if err != nil {            fmt.Println("read:", err)            return        }        fmt.Printf("received: %s\n", msg)    }}func timeWriter(conn *websocket.Conn) {    for {        time.Sleep(time.Second * 2)        websocket.Message.Send(conn, "hello world")    }}

client的代碼,每隔2秒鐘發送hello world到server,然後阻塞在Read函數。需要注意的是origin必須以“http://1111111/” 這種標準的URI格式,否則報錯“invalid URI for request”。 關閉進程、網路斷線等異常情況 關閉進程

無論server還是client,關閉進程,對端Read都會立刻收到EOF,對EOF做處理即可。 網路斷線 測試
client和server部署在不同機器上,client每隔2秒中向server發送資料,server收到後回吐給用戶端。這個過程中,拔掉client的網線。 測試結果
斷網後,client一定時間內寫都能成功返回,但是因為斷網實際沒有發送出去,資料寫到了底層tcp的緩衝區。 過一段時間後,1分鐘左右,client Read返回錯誤“read: operation timed out”。Write會返回“write: broken pipe”。這個可能是Go中websocket實現時加了逾時機制,也有可能是設定了底層TCP SO_KEEPALIVE,檢測到了網路不可用。 在Read/Write返回錯誤之前,重新連上網路,可以繼續發送和接受資料。這個可以從TCP的實現上解釋。TCP串連並不是物理串連,本質上就是串連兩端各自系統核心維護的一個四元組。用戶端斷線,在一定時間內並不會導致四元組的釋放。所以當連上網線後此TCP串連可以自動回復,繼續進行正常的網路操作。 斷線重連到其他網路,相當於斷網。這個很好解釋,連上其他網路,IP地址都改變了,之前的四元組不可用。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.