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

gin使用websocket實(shí)現(xiàn)數(shù)據(jù)實(shí)時(shí)推送

 更新時(shí)間:2026年05月10日 10:05:26   作者:鋒行天下  
本文主要介紹了gin使用websocket實(shí)現(xiàn)數(shù)據(jù)實(shí)時(shí)推送,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

業(yè)務(wù)場(chǎng)景

今天給自己的項(xiàng)目加了幾個(gè)echarts圖表,主要用以顯示我的幾個(gè)系統(tǒng)的近一周訪問(wèn)量,大概是這個(gè)樣子

三個(gè)圖標(biāo)分別是:我的簡(jiǎn)歷訪問(wèn)量,我的音樂(lè)訪問(wèn)量,簡(jiǎn)歷和音樂(lè)訪問(wèn)量對(duì)比

1.數(shù)據(jù)采集

這個(gè)訪問(wèn)信息的采集是在我的簡(jiǎn)歷和我的音樂(lè)頁(yè)面提交信息,也就是個(gè)很簡(jiǎn)單的接口,提交用戶訪問(wèn)該頁(yè)面的時(shí)間和頁(yè)面類型(簡(jiǎn)歷頁(yè)面或者是音樂(lè)頁(yè)面)

2,數(shù)據(jù)整理

把近一周時(shí)間內(nèi)每天的訪問(wèn)量整理出來(lái)返回給前端系統(tǒng)

// 獲取我的音樂(lè)本周訪問(wèn)量
func (this Personal) GetMusicData(ctx *gin.Context) {
	now := time.Now()
	year, month, day := now.Date()
	// 今天的時(shí)間
	today := time.Date(year, month, day, 0, 0, 0, 0, time.Local)
	//今天的時(shí)間-1
	t1 := today.AddDate(0, 0, -1)
	//今天的時(shí)間-2
	t2 := today.AddDate(0, 0, -2)
	//今天的時(shí)間-3
	t3 := today.AddDate(0, 0, -3)
	//今天的時(shí)間-4
	t4 := today.AddDate(0, 0, -4)
	//今天的時(shí)間-5
	t5 := today.AddDate(0, 0, -5)
	//今天的時(shí)間-6
	t6 := today.AddDate(0, 0, -6)
	tourist1 := []modules.Tourist{}
	tourist2 := []modules.Tourist{}
	tourist3 := []modules.Tourist{}
	tourist4 := []modules.Tourist{}
	tourist5 := []modules.Tourist{}
	tourist6 := []modules.Tourist{}
	tourist7 := []modules.Tourist{}

	err := modules.DB.Where("scene LIKE ? AND add_time > ?", "%music%", today).Find(&tourist1).Error
	err2 := modules.DB.Where("scene LIKE ? AND add_time > ? AND add_time < ?", "%music%", t1, today).Find(&tourist2).Error
	err3 := modules.DB.Where("scene LIKE ? AND add_time > ? AND add_time < ?", "%music%", t2, t1).Find(&tourist3).Error
	err4 := modules.DB.Where("scene LIKE ? AND add_time > ? AND add_time < ?", "%music%", t3, t2).Find(&tourist4).Error
	err5 := modules.DB.Where("scene LIKE ? AND add_time > ? AND add_time < ?", "%music%", t4, t3).Find(&tourist4).Error
	err6 := modules.DB.Where("scene LIKE ? AND add_time > ? AND add_time < ?", "%music%", t5, t4).Find(&tourist4).Error
	err7 := modules.DB.Where("scene LIKE ? AND add_time > ? AND add_time < ?", "%music%", t6, t5).Find(&tourist4).Error
	if err != nil || err2 != nil || err3 != nil || err4 != nil || err5 != nil || err6 != nil || err7 != nil {
		ctx.JSON(400, gin.H{
			"message": "獲取失敗",
		})
	} else {
		arr := []int{len(tourist7), len(tourist6), len(tourist5), len(tourist4), len(tourist3), len(tourist2), len(tourist1)}
		ctx.JSON(200, gin.H{
			"message": "獲取成功",
			"data":    arr,
		})
	}
}

這是整理音樂(lè)頁(yè)面訪問(wèn)量的函數(shù),簡(jiǎn)歷頁(yè)面同理

3,前端獲取到數(shù)據(jù)后把數(shù)據(jù)綁定給echarts圖標(biāo)

... ... 此處省略前端代碼若干行

4,重點(diǎn)部分:使用websocket和服務(wù)端生成長(zhǎng)鏈接,訪問(wèn)量變化了實(shí)時(shí)通知前端獲取最新數(shù)據(jù)

后端部分
"github.com/gorilla/websocket"

var upgrader = websocket.Upgrader{
	CheckOrigin: func(r *http.Request) bool {
		return true
	},
}
//這里聲明一個(gè)鏈接池
var conns []*websocket.Conn

func (this UserController) WS(w http.ResponseWriter, r *http.Request) {
	c, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		println("upgrade錯(cuò)誤:", err)
		return
	}
	defer c.Close()
        //把所有鏈接存在鏈接池里
	conns = append(conns, c)
	for {
		_, _, err := c.ReadMessage()
		if err != nil {
			println("read:", err)
			break
		}
	}
}

在數(shù)據(jù)采集到函數(shù)里,當(dāng)收到有人訪問(wèn)那兩個(gè)頁(yè)面,把鏈接池里的鏈接都通知一遍

func (this UserController) AddTourist(ctx *gin.Context) {
	scene := ctx.Request.FormValue("scene")
	message := ctx.Request.FormValue("message")
	time := time.Now().UTC()
	tourist := &modules.Tourist{
		Scene:   scene,
		Message: message,
		AddTime: time,
	}
	err := modules.DB.Model(&modules.Tourist{}).Create(&tourist).Error
	if err != nil {
		ctx.JSON(400, gin.H{
			"message": "新增瀏覽用戶信息失敗",
		})
	} else {
        //這里是重點(diǎn),循環(huán)鏈接池,廣播消息,消息類型隨便定,只要你前端知道就行,我這里通知一個(gè)數(shù)字1
		for i := range conns {
                        if index := strings.Index(scene, "jianli"); index != -1 {
				conns[i].WriteMessage(websocket.TextMessage, []byte("jianli"))
			} else if index := strings.Index(scene, "music"); index != -1 {
				conns[i].WriteMessage(websocket.TextMessage, []byte("music"))
			}
		}
		ctx.JSON(200, gin.H{
			"message": "新增瀏覽用戶信息成功!",
		})
	}
}

然后是管理系統(tǒng)收到推送的消息,重新刷新數(shù)據(jù),這樣就實(shí)現(xiàn)了數(shù)據(jù)隨訪問(wèn)量實(shí)時(shí)變化的功能

const websocket=new WebSocket("ws://xxx.xxx.xxx.xxx:8088/ws")
websocket.onopen=(evt)=>{
  console.log("鏈接成功")
}
websocket.onmessage=(evt)=>{
//收到后端推送的消息,刷新對(duì)應(yīng)數(shù)據(jù)
  if(evt.data=="jianli"){
    refreshChartJL()
  }else if(evt.data=="music"){
    refreshChartMusic()
  }
}
websocket.onclose=()=>{
  console.log("鏈接關(guān)閉")
}
const getAllData=()=>{
    ...
    ...
    ...
}

總結(jié):這個(gè)功能實(shí)現(xiàn)下來(lái),也并不難,但一定要?jiǎng)邮謱?shí)現(xiàn)一下,如果你有啥疑問(wèn),可以留言,我每天都能看到

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

相關(guān)文章

  • 如何用go操作iptables和ipset設(shè)置黑白名單

    如何用go操作iptables和ipset設(shè)置黑白名單

    這篇文章主要介紹了如何用go操作iptables和ipset設(shè)置黑白名單問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-06-06
  • Go語(yǔ)言的GoRoot和GoPath的區(qū)別小結(jié)

    Go語(yǔ)言的GoRoot和GoPath的區(qū)別小結(jié)

    Go語(yǔ)言通過(guò)GOROOT和GOPATH配置開(kāi)發(fā)環(huán)境,GOROOT指定Go安裝目錄,GOPATH傳統(tǒng)模式下定義工作區(qū),存放項(xiàng)目代碼和依賴,下面就來(lái)詳細(xì)的介紹一下兩者的區(qū)別,感興趣的可以了解一下
    2025-10-10
  • 解決golang結(jié)構(gòu)體tag編譯錯(cuò)誤的問(wèn)題

    解決golang結(jié)構(gòu)體tag編譯錯(cuò)誤的問(wèn)題

    這篇文章主要介紹了解決golang結(jié)構(gòu)體tag編譯錯(cuò)誤的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-05-05
  • Go打包靜態(tài)文件的兩種方式

    Go打包靜態(tài)文件的兩種方式

    使用 Go 開(kāi)發(fā)應(yīng)用的時(shí)候,有時(shí)會(huì)遇到需要讀取靜態(tài)資源的情況,如果不打包處理這種靜態(tài)文件:發(fā)布單獨(dú)掛載這種靜態(tài)文件相對(duì)比較麻煩,就有人會(huì)想辦法把靜態(tài)資源文件打包進(jìn) Go 的程序文件中,下面介紹兩種打包方式:go-bindata、go:embed,需要的朋友可以參考下
    2024-04-04
  • 解決Golang中ResponseWriter的一個(gè)坑

    解決Golang中ResponseWriter的一個(gè)坑

    這篇文章主要介紹了解決Golang中ResponseWriter的一個(gè)坑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-04-04
  • Go1.16新特性embed打包靜態(tài)資源文件實(shí)現(xiàn)

    Go1.16新特性embed打包靜態(tài)資源文件實(shí)現(xiàn)

    這篇文章主要為大家介紹了Go?1.16新特性embed打包靜態(tài)資源文件的實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • Go語(yǔ)言中轉(zhuǎn)換JSON數(shù)據(jù)簡(jiǎn)單例子

    Go語(yǔ)言中轉(zhuǎn)換JSON數(shù)據(jù)簡(jiǎn)單例子

    這篇文章主要介紹了Go語(yǔ)言中轉(zhuǎn)換JSON數(shù)據(jù)簡(jiǎn)單例子,本文先定義了一個(gè)結(jié)構(gòu)體,然后把JSON綁定到結(jié)構(gòu)體上實(shí)現(xiàn)讀取,需要的朋友可以參考下
    2014-10-10
  • 使用Go開(kāi)發(fā)一個(gè)文件同步小工具(附源碼)

    使用Go開(kāi)發(fā)一個(gè)文件同步小工具(附源碼)

    這篇文章主要為大家詳細(xì)介紹了如何使用Go開(kāi)發(fā)一個(gè)文件同步小工具并附上源碼,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-11-11
  • Go語(yǔ)言參數(shù)傳遞是傳值還是傳引用

    Go語(yǔ)言參數(shù)傳遞是傳值還是傳引用

    Go?語(yǔ)言到底是傳值(值傳遞),還是傳引用(引用傳遞)?本文就詳細(xì)介紹一下,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • GO語(yǔ)言并發(fā)之好用的sync包詳解

    GO語(yǔ)言并發(fā)之好用的sync包詳解

    標(biāo)準(zhǔn)庫(kù)中的sync包在我們的日常開(kāi)發(fā)中用的頗為廣泛,那么大家對(duì)sync包的用法知道多少呢,這篇文章就大致講一下sync包和它的使用,感興趣的可以學(xué)習(xí)一下
    2022-12-12

最新評(píng)論

灵璧县| 五家渠市| 固始县| 莱芜市| 古交市| 宁海县| 富裕县| 浮山县| 康保县| 平塘县| 芦山县| 淮安市| 清河县| 百色市| 东海县| 岳池县| 朝阳市| 康定县| 秦安县| 延川县| 梨树县| 泸溪县| 军事| 鹤壁市| 临安市| 富民县| 湛江市| 城固县| 金乡县| 长子县| 岚皋县| 长治市| 乾安县| 滨海县| 龙海市| 上思县| 临沧市| 哈密市| 霞浦县| 沂源县| 新野县|