91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

goland如何實現websocket?server

發布時間:2022-06-08 09:26:11 來源:億速云 閱讀:227 作者:zzz 欄目:開發技術

這篇文章主要介紹了goland如何實現websocket server的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇goland如何實現websocket server文章都會有所收獲,下面我們一起來看看吧。

goland如何實現websocket?server

goland如何實現websocket?server

話不多說上全部代碼:

package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
	"net/http"
	uuid "github.com/satori/go.uuid"
)

//Client:單個websocket
type Client struct {
	Id      string
	Socket  *websocket.Conn
	Message chan []byte
}

var clientCount   uint // 客戶端數量

//從websocket中直接讀取數據
func (c *Client) Read() {
	defer func() {
		//客戶端關閉
		if err := c.Socket.Close(); err != nil {
			fmt.Printf("client [%s] disconnect err: %s", c.Id, err)
		}
		//關閉后直接注銷客戶端
		//WebsocketManager.UnRegisterClient(c)
		clientCount--
		fmt.Printf("client [%s],客戶端關閉:[%s],Count [%d]\n", c.Id, websocket.CloseMessage, clientCount)
	}()

	for {
		messageType, message, err := c.Socket.ReadMessage()
		//讀取數據失敗
		if err != nil || messageType == websocket.CloseMessage {
			fmt.Printf("client [%s],數據讀取失敗或通道關閉:[%s],客戶端連接狀態:[%s]\n", c.Id, err.Error(), websocket.CloseMessage)
			break
		}

		// TODO 解析發送過來的參數
		//var data ReadData
		//err = json.Unmarshal(message, &data)
		//if err != nil {
		//  fmt.Println("數據解析失敗")
		//	return
		//}

		// TODO 前端請求返回數據到指定客戶端

		// 簡單測試
		c.Message <- message


	}
}

//寫入數據到websocket中
func (c *Client) Write() {
	defer func() {
		//客戶端關閉
		if err := c.Socket.Close(); err != nil {
			fmt.Printf("client [%s] disconnect err: %s \n", c.Id, err)
			return
		}
		//關閉后直接注銷客戶端
		//WebsocketManager.UnRegisterClient(c)
		clientCount--
		fmt.Printf("client [%s],客戶端關閉:[%s]\n", c.Id, websocket.CloseMessage)
	}()

	for {
		select {
		case message, ok := <-c.Message:

			if !ok {
				//數據寫入失敗,關閉通道
				fmt.Printf("client [%s],客戶端連接狀態:[%s]\n", c.Id, websocket.CloseMessage)
				_ = c.Socket.WriteMessage(websocket.CloseMessage, []byte{})
				//消息通道關閉后直接注銷客戶端
				return
			}

			err := c.Socket.WriteMessage(websocket.TextMessage, message)
			if err != nil {
				fmt.Printf("client [%s] write message err: %s \n", c.Id, err)
				return
			}
		}
	}
}


// 方法二: 通過對象創建  客戶端連接
func WsClient(context *gin.Context) {
	upGrande := websocket.Upgrader{
		//設置允許跨域
		CheckOrigin: func(r *http.Request) bool {
			return true
		},
		//設置請求協議
		Subprotocols: []string{context.GetHeader("Sec-WebSocket-Protocol")},
	}
	//創建連接
	conn, err := upGrande.Upgrade(context.Writer, context.Request, nil)
	if err != nil {
		fmt.Printf("websocket connect error: %s", context.Param("channel"))
		//format.NewResponseJson(context).Error(51001)
		return
	}
	//生成唯一標識client_id
	var uuid = uuid.NewV4().String()
	client := &Client{
		Id:      uuid,
		Socket:  conn,
		Message: make(chan []byte, 1024),
	}
	//注冊
	//ws.WebsocketManager.RegisterClient(client)
	clientCount++

	//起協程,實時接收和回復數據
	go client.Read()
	go client.Write()
}

// 方法一: 直接創建客戶端
func NewConnection(c *gin.Context) {
	// 定義同源檢查,這里只作簡單試驗不校驗
	upGrader := websocket.Upgrader{
	   CheckOrigin: func(r *http.Request) bool {
	       return true
	   },
	}
	 ws, err := upGrader.Upgrade(c.Writer, c.Request, nil)
	//ws, err := websocket.Upgrade(c.Writer, c.Request, nil, 1024, 1024)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"msg": "服務端錯誤",
		})
		return
	}


	var message = make(chan []byte)

	go func() {
		defer ws.Close()

		for {
			fmt.Println("start transfer message")
			msgType, msg, err := ws.ReadMessage()
			if err != nil || websocket.CloseMessage == msgType {
				fmt.Println("webSocket read error")
				return
			}
			message <- msg
		}

	}()

	go func() {
		defer ws.Close()

		for {
			mm, ok := <- message

			if !ok {
				//數據寫入失敗,關閉通道
				fmt.Printf("客戶端連接狀態:[%s]\n", websocket.CloseMessage)
				_ = ws.WriteMessage(websocket.CloseMessage, []byte{})
				//消息通道關閉后直接注銷客戶端
				return
			}

			err := ws.WriteMessage(websocket.TextMessage, mm)
			if err != nil {
				fmt.Println("webSocket write error")
				return
			}
		}
	}()

	//for {
	//
	//}

	 開始通信
	//for {
	//	fmt.Println("start transfer message")
	//	msgType, msg, err := ws.ReadMessage()
	//	if err != nil {
	//		fmt.Println("webSocket read error")
	//		return
	//	}
	//	err = ws.WriteMessage(msgType, msg)
	//	if err != nil {
	//		fmt.Println("webSocket write error")
	//		return
	//	}
	//}
}

// ws://127.0.0.1:9090/wsTest
func main() {
	r := gin.Default()

	// 方法一: 直接創建客戶端
	r.GET("/wsTest", NewConnection)
	// 方法二: 通過對象創建  客戶端連接
	r.GET("/wsTest1", WsClient)

	clientCount = 0
	r.Run("127.0.0.1:9090")
}

關于“goland如何實現websocket server”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“goland如何實現websocket server”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

新建县| 黑山县| 隆安县| 肃北| 全州县| 普兰店市| 乐陵市| 东山县| 开封市| 宝兴县| 分宜县| 南昌市| 莱西市| 饶河县| 图片| 林口县| 荔浦县| 镶黄旗| 镇宁| 板桥市| 阿合奇县| 商水县| 左权县| 广平县| 巴南区| 任丘市| 巴彦县| 肥东县| 宜黄县| 江门市| 凤山县| 梁平县| 郓城县| 寻乌县| 乌拉特后旗| 宁乡县| 随州市| 石首市| 庆云县| 防城港市| 长泰县|