" />

最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

goland 實(shí)現(xiàn)websocket server的示例代碼

 更新時(shí)間:2022年06月07日 15:06:31   作者:shw03201  
本文主要介紹了goland 實(shí)現(xiàn)websocket server的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

采用go 實(shí)現(xiàn)的websocket,已經(jīng)調(diào)試通過在此記錄。

測(cè)試工具網(wǎng)址:https://www.idcd.com/tool/socket

在這里插入圖片描述

在這里插入圖片描述

話不多說上全部代碼:

package main

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

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

var clientCount   uint // 客戶端數(shù)量

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

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

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

		// TODO 前端請(qǐng)求返回?cái)?shù)據(jù)到指定客戶端

		// 簡(jiǎn)單測(cè)試
		c.Message <- message


	}
}

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

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

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

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


// 方法二: 通過對(duì)象創(chuàng)建  客戶端連接
func WsClient(context *gin.Context) {
	upGrande := websocket.Upgrader{
		//設(shè)置允許跨域
		CheckOrigin: func(r *http.Request) bool {
			return true
		},
		//設(shè)置請(qǐng)求協(xié)議
		Subprotocols: []string{context.GetHeader("Sec-WebSocket-Protocol")},
	}
	//創(chuàng)建連接
	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
	}
	//生成唯一標(biāo)識(shí)client_id
	var uuid = uuid.NewV4().String()
	client := &Client{
		Id:      uuid,
		Socket:  conn,
		Message: make(chan []byte, 1024),
	}
	//注冊(cè)
	//ws.WebsocketManager.RegisterClient(client)
	clientCount++

	//起協(xié)程,實(shí)時(shí)接收和回復(fù)數(shù)據(jù)
	go client.Read()
	go client.Write()
}

// 方法一: 直接創(chuàng)建客戶端
func NewConnection(c *gin.Context) {
	// 定義同源檢查,這里只作簡(jiǎn)單試驗(yàn)不校驗(yàn)
	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": "服務(wù)端錯(cuò)誤",
		})
		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 {
				//數(shù)據(jù)寫入失敗,關(guān)閉通道
				fmt.Printf("客戶端連接狀態(tài):[%s]\n", websocket.CloseMessage)
				_ = ws.WriteMessage(websocket.CloseMessage, []byte{})
				//消息通道關(guān)閉后直接注銷客戶端
				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()

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

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

拷貝全部代碼到工程即可測(cè)試。

到此這篇關(guān)于goland 實(shí)現(xiàn)websocket server的示例代碼的文章就介紹到這了,更多相關(guān)goland 實(shí)現(xiàn)websocket server內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • GO實(shí)現(xiàn)跳躍表的示例詳解

    GO實(shí)現(xiàn)跳躍表的示例詳解

    跳表全稱叫做跳躍表,簡(jiǎn)稱跳表,是一個(gè)隨機(jī)化的數(shù)據(jù)結(jié)構(gòu),實(shí)質(zhì)就是一種可以進(jìn)行二分查找的有序鏈表。本文將利用GO語言編寫一個(gè)跳表,需要的可以參考一下
    2022-12-12
  • 關(guān)于go-zero單體服務(wù)使用泛型簡(jiǎn)化注冊(cè)Handler路由的問題

    關(guān)于go-zero單體服務(wù)使用泛型簡(jiǎn)化注冊(cè)Handler路由的問題

    這篇文章主要介紹了go-zero單體服務(wù)使用泛型簡(jiǎn)化注冊(cè)Handler路由,涉及到Golang環(huán)境安裝及配置Go Module的相關(guān)知識(shí),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-07-07
  • go-cqhttp智能聊天功能的實(shí)現(xiàn)

    go-cqhttp智能聊天功能的實(shí)現(xiàn)

    這篇文章主要介紹了go-cqhttp智能聊天功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-09-09
  • Go語言中的函數(shù)式編程實(shí)踐

    Go語言中的函數(shù)式編程實(shí)踐

    這篇文章主要介紹了Go語言中的函數(shù)式編程實(shí)踐,主要講解Go語言中的函數(shù)式編程概念和使用。小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-05-05
  • Golang報(bào)“import cycle not allowed”錯(cuò)誤的2種解決方法

    Golang報(bào)“import cycle not allowed”錯(cuò)誤的2種解決方法

    這篇文章主要給大家介紹了關(guān)于Golang報(bào)"import cycle not allowed"錯(cuò)誤的2種解決方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以們下面隨著小編來一起看看吧
    2018-08-08
  • Golang錯(cuò)誤處理:異常捕捉和恢復(fù)機(jī)制

    Golang錯(cuò)誤處理:異常捕捉和恢復(fù)機(jī)制

    Golang中,異常處理是通過 defer + panic + recover 的方式來實(shí)現(xiàn)的,使用 defer 可以將清理操作注冊(cè)到函數(shù)執(zhí)行完畢后執(zhí)行,而 panic 和 recover 可以用于處理異常,通過組合使用這些功能,可以實(shí)現(xiàn)更加健壯的程序
    2024-01-01
  • 使用Golang創(chuàng)建單獨(dú)的WebSocket會(huì)話

    使用Golang創(chuàng)建單獨(dú)的WebSocket會(huì)話

    WebSocket是一種在Web開發(fā)中非常常見的通信協(xié)議,它提供了雙向、持久的連接,適用于實(shí)時(shí)數(shù)據(jù)傳輸和實(shí)時(shí)通信場(chǎng)景,本文將介紹如何使用 Golang 創(chuàng)建單獨(dú)的 WebSocket 會(huì)話,包括建立連接、消息傳遞和關(guān)閉連接等操作,需要的朋友可以參考下
    2023-12-12
  • GO中?分組聲明與array,?slice,?map函數(shù)

    GO中?分組聲明與array,?slice,?map函數(shù)

    這篇文章主要介紹了GO中?分組聲明與array,slice,map函數(shù),Go語言中,同時(shí)聲明多個(gè)常量、變量,或者導(dǎo)入多個(gè)包時(shí),可采用分組的方式進(jìn)行聲明,下面詳細(xì)介紹需要的小伙伴可以參考一下
    2022-03-03
  • Windows下在CMD下執(zhí)行Go出現(xiàn)中文亂碼的解決方法

    Windows下在CMD下執(zhí)行Go出現(xiàn)中文亂碼的解決方法

    在cmd下運(yùn)行g(shù)o程序或者是GOLAND的Terminal下運(yùn)行g(shù)o程序會(huì)出現(xiàn)中文亂碼的情況。本文就詳細(xì)的介紹下解決方法,具有一定的參考價(jià)值,感興趣的可以了解一下
    2021-12-12
  • go等待一組協(xié)程結(jié)束的操作方式

    go等待一組協(xié)程結(jié)束的操作方式

    這篇文章主要介紹了go等待一組協(xié)程結(jié)束的操作方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05

最新評(píng)論

新泰市| 台山市| 徐闻县| 修文县| 奉贤区| 万全县| 和平区| 中山市| 化州市| 勐海县| 香河县| 高要市| 房产| 博乐市| 甘德县| 墨竹工卡县| 长垣县| 洛浦县| 玛沁县| 百色市| 内黄县| 获嘉县| 霍林郭勒市| 博罗县| 江达县| 汝城县| 陆丰市| 二手房| 万载县| 年辖:市辖区| 浦江县| 射洪县| 阿拉善左旗| 文登市| 井研县| 黄浦区| 花莲县| 北票市| 潜山县| 宁远县| 阳曲县|