<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          【GoCN酷Go推薦】Golang官方認可的websocket庫-gorilla/websocket

          共 6281字,需瀏覽 13分鐘

           ·

          2021-07-18 14:17

          推薦理由

          Golang官方標準庫實現(xiàn)的websocket在功能上有些欠缺,本次介紹的gorilla/websocket庫,是Gorilla出品的速度快、質量高,并且被廣泛使用的websocket庫,很好的彌補了標準庫功能上的欠缺。另外Gorilla Web toolkit包含多個實用的HTTP應用相關的工具庫,感興趣可以到官網主頁https://www.gorillatoolkit.org自取。

          功能介紹

          gorilla/websocket庫是 RFC 6455 定義的websocket協(xié)議的一種實現(xiàn),在數(shù)據(jù)收發(fā)方面,提供Data Messages、Control Messages兩類message粒度的讀寫API;性能方面,提供Buffers和Compression的相關配置選項;安全方面,可通過CheckOrigin來控制是否支持跨域。

          gorilla/websocket庫和官方實現(xiàn)的對比

          摘自 gorilla GitHub 主頁


          github.com/gorillagolang.org/x/net



          RFC 6455 Features
          Passes Autobahn Test SuiteYesNo
          Receive fragmented messageYesNo, see note 1
          Send close messageYesNo
          Send pings and receive pongsYesNo
          Get the type of a received data messageYesYes, see note 2
          Other Features
          Compression ExtensionsExperimentalNo
          Read message using io.ReaderYesNo, see note 3
          Write message using io.WriteCloserYesNo, see note 3

          Notes:

          1. Large messages are fragmented in Chrome's new WebSocket implementation.
          2. The application can get the type of a received data message by implementing a Codec marshalfunction.
          3. The go.net io.Reader and io.Writer operate across WebSocket frame boundaries. Read returns when the input buffer is full or a frame boundary is encountered. Each call to Write sends a single frame message. The Gorilla io.Reader and io.WriteCloser operate on a single WebSocket message.

          使用指南

          安裝

          go get github.com/gorilla/websocket

          基礎示例

          下面以一個簡單的echo來說明gorilla/websocket庫基本使用。

          client代碼:

          package main

          import (
           "flag"
           "log"
           "net/url"
           "os"
           "os/signal"
           "time"

           "github.com/gorilla/websocket"
          )

          var addr = flag.String("addr""localhost:8080""http service address")

          func main() {
           flag.Parse()
           log.SetFlags(0)

              // 用來接收命令行的終止信號
           interrupt := make(chan os.Signal, 1)
           signal.Notify(interrupt, os.Interrupt)

              // 和服務端建立連接
           u := url.URL{Scheme: "ws", Host: *addr, Path: "/echo"}
           log.Printf("connecting to %s", u.String())

           c, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
           if err != nil {
            log.Fatal("dial:", err)
           }
           defer c.Close()

           done := make(chan struct{})

           go func() {
            defer close(done)
            for {
                      // 從接收服務端message
             _, message, err := c.ReadMessage()
             if err != nil {
              log.Println("read:", err)
              return
             }
             log.Printf("recv: %s", message)
            }
           }()

           ticker := time.NewTicker(time.Second)
           defer ticker.Stop()

           for {
            select {
            case <-done:
             return
                  case t := <-ticker.C:
                      // 向服務端發(fā)送message
             err := c.WriteMessage(websocket.TextMessage, []byte(t.String()))
             if err != nil {
              log.Println("write:", err)
              return
             }
            case <-interrupt:
             log.Println("interrupt")

             // 收到命令行終止信號,通過發(fā)送close message關閉連接。
             err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
             if err != nil {
              log.Println("write close:", err)
              return
                      }
                      // 收到接收協(xié)程完成的信號或者超時,退出
             select {
             case <-done:
             case <-time.After(time.Second):
             }
             return
            }
           }
          }

          server代碼:

          package main

          import (
           "flag"
           "html/template"
           "log"
           "net/http"

           "github.com/gorilla/websocket"
          )

          var addr = flag.String("addr""localhost:8080""http service address")

          var upgrader = websocket.Upgrader{}

          func echo(w http.ResponseWriter, r *http.Request) {
              // 完成和Client HTTP >>> WebSocket的協(xié)議升級
           c, err := upgrader.Upgrade(w, r, nil)
           if err != nil {
            log.Print("upgrade:", err)
            return
           }
           defer c.Close()
           for {
                  // 接收客戶端message
            mt, message, err := c.ReadMessage()
            if err != nil {
             log.Println("read:", err)
             break
            }
                  log.Printf("recv: %s", message)
                  // 向客戶端發(fā)送message
            err = c.WriteMessage(mt, message)
            if err != nil {
             log.Println("write:", err)
             break
            }
           }
          }

          func main() {
           flag.Parse()
           log.SetFlags(0)
           http.HandleFunc("/echo", echo)
           log.Fatal(http.ListenAndServe(*addr, nil))
          }

          更多示例可以參考 https://github.com/gorilla/websocket/tree/master/examples

          總結

          gorilla/websocket庫是websocket協(xié)議的一種實現(xiàn),相比標準庫的實現(xiàn),封裝了協(xié)議細節(jié),使用者關注message粒度的API即可,但需要注意message的讀寫API非并發(fā)安全,使用時注意不要多個協(xié)程并發(fā)調用。

          參考資料

          1. https://github.com/gorilla/websocket

          還想了解更多嗎?

          更多請查看:https://github.com/gorilla/websocket

          歡迎加入我們GOLANG中國社區(qū):https://gocn.vip/


          《酷Go推薦》招募:


          各位Gopher同學,最近我們社區(qū)打算推出一個類似GoCN每日新聞的新欄目《酷Go推薦》,主要是每周推薦一個庫或者好的項目,然后寫一點這個庫使用方法或者優(yōu)點之類的,這樣可以真正的幫助到大家能夠學習到

          新的庫,并且知道怎么用。


          大概規(guī)則和每日新聞類似,如果報名人多的話每個人一個月輪到一次,歡迎大家報名!(報名地址:https://wj.qq.com/s2/7734329/3f51)


          掃碼也可以加入 GoCN 的大家族喲~







          瀏覽 67
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  最好看的2019中文大全在线观看 | 日韩av成人电影在线观看 | 欧美日韩操逼视屏 | 国产精品久久久久久久久夜色 | 热门视频 - 91爱爱 |