欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

golang開發(fā)?gorilla?websocket的使用示例詳解

 更新時間:2024年05月31日 09:15:37   作者:飛翔碼農(nóng)  
這篇文章主要介紹了golang開發(fā)?gorilla?websocket的使用示例詳解,介紹了websocket的簡單使用,我們使用的版本是1.3.0,具體操作方法跟隨小編一起學(xué)習(xí)吧

很多APP都需要主動向用戶推送消息,這就需要用到長連接的服務(wù),即我們通常提到的websocket,同樣也是使用socket服務(wù),通信協(xié)議是基本類似的,在go中用的最多的、也是最簡單的socket服務(wù)就是gorilla/websocket,它有21.1K的star,足以說明它的受歡迎程度, 它的github地址是 https://github.com/gorilla/websocket,我們的長連接服務(wù)也是通過gorilla/websocket改造出來的。

websocket的簡單使用

我們使用的版本是1.3.0,首先下載websocket
go get github.com/gorilla/websocket@v1.3.0

把websocket/examples/echo下面的 client.go server.go 現(xiàn)在下來拷貝到項目里面。
https://github.com/gorilla/websocket/blob/v1.3.0/examples/echo/server.go

https://github.com/gorilla/websocket/blob/v1.3.0/examples/echo/client.go

在一個終端執(zhí)行 websocket 服務(wù)
go run server.go

recv: 2024-04-16 15:09:45.805438 +0800 CST m=+1.007536889
recv: 2024-04-16 15:09:46.805425 +0800 CST m=+2.007517605
recv: 2024-04-16 15:09:47.806274 +0800 CST m=+3.008359325
recv: 2024-04-16 15:09:48.80495 +0800 CST m=+4.007028866
recv: 2024-04-16 15:09:49.805743 +0800 CST m=+5.007816108
recv: 2024-04-16 15:09:50.806087 +0800 CST m=+6.008153310
recv: 2024-04-16 15:09:51.805348 +0800 CST m=+7.007407266

再打開一個終端執(zhí)行 go run client.go,充當(dāng)客戶端

connecting to ws://localhost:8080/echo
recv: 2024-04-16 15:09:45.805438 +0800 CST m=+1.007536889
recv: 2024-04-16 15:09:46.805425 +0800 CST m=+2.007517605
recv: 2024-04-16 15:09:47.806274 +0800 CST m=+3.008359325
recv: 2024-04-16 15:09:48.80495 +0800 CST m=+4.007028866
recv: 2024-04-16 15:09:49.805743 +0800 CST m=+5.007816108
recv: 2024-04-16 15:09:50.806087 +0800 CST m=+6.008153310
recv: 2024-04-16 15:09:51.805348 +0800 CST m=+7.007407266

我們看看這個簡單的例子。
client.go

go func() {
		defer close(done)
		for {
			_, 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:
			err := c.WriteMessage(websocket.TextMessage, []byte(t.String()))
			if err != nil {
				log.Println("write:", err)
				return
			}
		case <-interrupt:
			log.Println("interrupt")
			// Cleanly close the connection by sending a close message and then
			// waiting (with timeout) for the server to close the connection.
			err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
			if err != nil {
				log.Println("write close:", err)
				return
			}
			select {
			case <-done:
			case <-time.After(time.Second):
			}
			return
		}
	}

go func() 的 c.ReadMessage 不停的從socket里面讀取數(shù)據(jù)并且打印。
for 循環(huán)不停的從1秒的定時器里面讀取時間,寫到socket

server.go

for {
		mt, message, err := c.ReadMessage()
		if err != nil {
			log.Println("read:", err)
			break
		}
		log.Printf("recv: %s", message)
		err = c.WriteMessage(mt, message)
		if err != nil {
			log.Println("write:", err)
			break
		}
	}

for c.ReadMessage 循環(huán)不停的從 socket讀取數(shù)據(jù),把數(shù)據(jù)打印之后,又寫給客戶端。
這是大致的websocket 客戶端與服務(wù)端通信的簡單例子。

改成自定義的協(xié)議

我們使用二進制數(shù)據(jù)流,自定義的協(xié)議是這樣的,
先是無符號的 uint 占4個字節(jié),表示行為邏輯,比如111-獲取信息, 110- 加好友等等
后面是具體的數(shù)據(jù),跟HTTP請求的GET或者POST參數(shù)類似,具體數(shù)據(jù)格式定義好就行,比如可以使用JSON數(shù)據(jù)、可以使用RPC定義好的數(shù)據(jù)格式

修改完之后 client.go 代碼是這樣的

for {
		select {
		case <-done:
			return
		case <-ticker.C:
			buf := bytes.NewBuffer([]byte{})
			binary.Write(buf, binary.BigEndian, uint32(110))
			binary.Write(buf, binary.BigEndian, []byte("我們都好"))
			err := c.WriteMessage(websocket.BinaryMessage, buf.Bytes())
			if err != nil {
				log.Println("write:", err)
				return
			}
		case <-interrupt:
			log.Println("interrupt")
			// Cleanly close the connection by sending a close message and then
			// waiting (with timeout) for the server to close the connection.
			err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
			if err != nil {
				log.Println("write close:", err)
				return
			}
			select {
			case <-done:
			case <-time.After(time.Second):
			}
			return
		}
	}

主要是這個

buf := bytes.NewBuffer([]byte{})
binary.Write(buf, binary.BigEndian, uint32(110))
binary.Write(buf, binary.BigEndian, []byte("我們都好"))

創(chuàng)建一個bytes Buffer
寫入一個uint32,占4個字節(jié),表示行為邏輯
寫入行為邏輯具體的數(shù)據(jù)
以上采用大端通信

修改之后的 server.go

for {
		mt, message, err := c.ReadMessage()
		if err != nil {
			log.Println("read:", err)
			break
		}
		log.Println("messagetype:%d", mt)
		log.Println("messagelen:%d", len(message))
		log.Println("messagetype:%d", binary.BigEndian.Uint32(message[0:4]))
		log.Println("recv: %s", string(message[4:]))
		err = c.WriteMessage(mt, message)
		if err != nil {
			log.Println("write:", err)
			break
		}
	}

mt websocket 類型
TextMessage = 1 文本類型傳傳輸
BinaryMessage = 2 字節(jié)類型傳輸

從socket里面獲取到message之后
先取前4個字節(jié),表示邏輯行為
再取剩余的字節(jié),表示行為邏輯需要的參數(shù)

我們重新執(zhí)行一下,server.go 和 client.go

go run client.go
connecting to ws://localhost:8080/echo
recv: n我們都好
recv: n我們都好
go run server.go
messagetype:%d 2
messagelen:%d 16
messagetype:%d 110
recv: %s 我們都好

messagetype=2表示二進制通信
message長度是16,前四個字節(jié)是無符號整形,四個漢字占12個字節(jié),一共16個字節(jié),無符號uint是110表示加好友。

這就是一個簡單自定義協(xié)議的socket服務(wù)。

如果有需要登錄鑒權(quán)的話,在server.go中可以從r *http.Request 獲取header或者cookie,進行登錄鑒權(quán)驗證。

生產(chǎn)的部署

因為是 websocket 協(xié)議,如果有代理服務(wù)器的話,需要在各代理服務(wù)器上的Nginx做協(xié)議升級,將HTTP 升級為 websocket ,比如下面的代理服務(wù)器。

map $http_upgrade $connection_upgrade {
default upgrade;
''      close;
}
server {
    listen 80;
    location /serv/ {
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_connect_timeout 3;
        proxy_redirect     off;
        proxy_read_timeout 3600;
        proxy_send_timeout 3600;
        proxy_pass http://push_web/serv/;
    }
}

到此這篇關(guān)于golang開發(fā) gorilla websocket的使用示例詳解的文章就介紹到這了,更多相關(guān)golang開發(fā) gorilla websocket內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Go語言實現(xiàn)的可讀性更高的并發(fā)神庫詳解

    Go語言實現(xiàn)的可讀性更高的并發(fā)神庫詳解

    這篇文章主要為大家介紹了Go語言實現(xiàn)的可讀性更高的并發(fā)神庫詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-01-01
  • golang利用redis和gin實現(xiàn)保存登錄狀態(tài)校驗登錄功能

    golang利用redis和gin實現(xiàn)保存登錄狀態(tài)校驗登錄功能

    這篇文章主要介紹了golang利用redis和gin實現(xiàn)保存登錄狀態(tài)校驗登錄功能,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2024-01-01
  • Go實現(xiàn)替換(覆蓋)文件某一行內(nèi)容的示例代碼

    Go實現(xiàn)替換(覆蓋)文件某一行內(nèi)容的示例代碼

    本文主要介紹了Go實現(xiàn)替換(覆蓋)文件某一行內(nèi)容的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • 基于Go+OpenCV實現(xiàn)人臉識別功能的詳細(xì)示例

    基于Go+OpenCV實現(xiàn)人臉識別功能的詳細(xì)示例

    OpenCV是一個強大的計算機視覺庫,提供了豐富的圖像處理和計算機視覺算法,本文將向你介紹在Mac上安裝OpenCV的步驟,并演示如何使用Go的OpenCV綁定庫進行人臉識別,需要的朋友可以參考下
    2023-07-07
  • Golang中基礎(chǔ)的命令行模塊urfave/cli的用法說明

    Golang中基礎(chǔ)的命令行模塊urfave/cli的用法說明

    這篇文章主要介紹了Golang中基礎(chǔ)的命令行模塊urfave/cli的用法說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • 詳解Golang中Context的三個常見應(yīng)用場景

    詳解Golang中Context的三個常見應(yīng)用場景

    Golang?context主要用于定義超時取消,取消后續(xù)操作,在不同操作中傳遞值。本文通過簡單易懂的示例進行說明,感興趣的可以了解一下
    2022-12-12
  • Golang接口使用教程詳解

    Golang接口使用教程詳解

    在?Go?語言中接口包含兩種含義:它既是方法的集合,?同時還是一種類型并且在Go?語言中是隱式實現(xiàn)的。本文通過示例詳細(xì)介紹了Golang接口的使用,需要的可以參考一下
    2022-09-09
  • Go條件控制語句詳解(if-else、switch和select)

    Go條件控制語句詳解(if-else、switch和select)

    條件語句用于檢查一個條件是否為真,并根據(jù)條件的真假來決定是否執(zhí)行相應(yīng)的代碼,下面這篇文章主要給大家介紹了關(guān)于Go條件控制語句(if-else、switch和select)的相關(guān)資料,需要的朋友可以參考下
    2024-03-03
  • 一文詳解Golang中的基礎(chǔ)語法

    一文詳解Golang中的基礎(chǔ)語法

    這篇文章主要為大家詳細(xì)介紹了Golang中基礎(chǔ)語法的相關(guān)知識,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)Golang有一定的幫助,感興趣的可以了解一下
    2023-03-03
  • 一文教你如何在Golang中用好泛型

    一文教你如何在Golang中用好泛型

    golang的泛型已經(jīng)出來了一年多了,從提案被接受開始我就在關(guān)注泛型了,好用是好用,但問題也很多,所以本文就來教大家如何在Golang中用好泛型吧
    2023-07-07

最新評論