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

go語言如何使用gin庫(kù)實(shí)現(xiàn)SSE長(zhǎng)連接

 更新時(shí)間:2023年06月09日 11:58:10   作者:合眾國(guó)的原野  
所謂長(zhǎng)連接指在一個(gè)TCP連接上可以連續(xù)發(fā)送多個(gè)數(shù)據(jù)包,在TCP連接保持期間,如果沒有數(shù)據(jù)包發(fā)送,需要雙方發(fā)檢測(cè)包以維持此連接,一般需要自己做在線維持,下面這篇文章主要給大家介紹了關(guān)于go語言如何使用gin庫(kù)實(shí)現(xiàn)SSE長(zhǎng)連接的相關(guān)資料,需要的朋友可以參考下

前言

項(xiàng)目需求:在go項(xiàng)目中實(shí)現(xiàn)SSE長(zhǎng)連接,耗時(shí)操作完成后,后端主動(dòng)通知前端消息。

1.建立長(zhǎng)連接

最主要的操作是修改請(qǐng)求中的Content-Type類型為"text/event-stream"。

需要注意幾點(diǎn),后端首先不能讓請(qǐng)求處理代碼跑完,如果跑完這個(gè)請(qǐng)求就會(huì)斷掉,保存的*gin.Context信息也就沒用了,因此要新建一個(gè)range chan維持處理狀態(tài)。

另外這里如果用for循環(huán)代替chan,會(huì)導(dǎo)致前端持續(xù)發(fā)送請(qǐng)求到后端。

import (
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/labstack/gommon/log"
	"net/http"
	"strings"
	"time"
)
 
var ifChannelsMapInit = false
 
var channelsMap = map[string]chan string{}
 
func initChannelsMap() {
	channelsMap = make(map[string]chan string)
}
 
func AddChannel(userEmail string, traceId string) {
	if !ifChannelsMapInit {
		initChannelsMap()
		ifChannelsMapInit = true
	}
	var newChannel = make(chan string)
	channelsMap[userEmail+traceId] = newChannel
	log.Infof("Build SSE connection for user = " + userEmail + ", trace id = " + traceId)
}
 
func BuildNotificationChannel(userEmail string, traceId string, c *gin.Context) {
	AddChannel(userEmail, traceId)
	c.Writer.Header().Set("Content-Type", "text/event-stream")
	c.Writer.Header().Set("Cache-Control", "no-cache")
	c.Writer.Header().Set("Connection", "keep-alive")
	w := c.Writer
	flusher, _ := w.(http.Flusher)
	closeNotify := c.Request.Context().Done()
	go func() {
		<-closeNotify
		delete(channelsMap, userEmail+traceId)
		log.Infof("SSE close for user = " + userEmail + ", trace id = " + traceId)
		return
	}()
	fmt.Fprintf(w, "data: %s\n\n", "--ping--")
	flusher.Flush()
	for msg := range channelsMap[userEmail+traceId] {
		fmt.Fprintf(w, "data: %s\n\n", msg)
		flusher.Flush()
	}
}

2.后端主動(dòng)通知前端消息

當(dāng)耗時(shí)操作處理完成后,調(diào)用該方法,前端會(huì)收到通知。

func SendNotification(userEmail string, messageBody string, actionType string) {
	log.Infof("Send notification to user = " + userEmail)
	var msg = dao.NotificationLog{}
	msg.MessageBody = messageBody
	msg.UserEmail = userEmail
	msg.Type = actionType
	msg.Status = UNREAD
	msg.CreateTime = time.Now()
	msg.Create()
	msgBytes, _ := json.Marshal(msg)
	for key := range channelsMap {
		if strings.Contains(key, userEmail) {
			channel := channelsMap[key]
			channel <- string(msgBytes)
		}
	}
}

3.調(diào)試

準(zhǔn)備兩個(gè)接口,分別是建立SSE和觸發(fā)耗時(shí)操作

GroupV1Rest.GET("/notification/socket-connection", controllers.SocketConnection)
GroupV1Rest.GET("/notification/export-excel", controllers.ExportExcel)

打開瀏覽器,進(jìn)入調(diào)試模式,在console頁輸入

e = new EventSource('/business/v1/notification/socket-connection');
e.onmessage = function(event) {
    console.log(event.data);
};

看到日志打印‘--ping--’,長(zhǎng)連接已建立

 此時(shí)發(fā)送第二個(gè)請(qǐng)求,調(diào)試模式看到通知被chan處理

返回瀏覽器,可以看到已經(jīng)收到通知

4.關(guān)閉長(zhǎng)連接 

前端關(guān)閉頁面后,自動(dòng)觸發(fā)監(jiān)聽事件,后端清理連接信息

總結(jié) 

到此這篇關(guān)于go語言如何使用gin庫(kù)實(shí)現(xiàn)SSE長(zhǎng)連接的文章就介紹到這了,更多相關(guān)go實(shí)現(xiàn)SSE長(zhǎng)連接內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Go channel實(shí)現(xiàn)原理分析

    Go channel實(shí)現(xiàn)原理分析

    Channel是go語言內(nèi)置的一個(gè)非常重要的特性,也是go并發(fā)編程的兩大基石之一,下面這篇文章主要給大家介紹了關(guān)于Go中channel的相關(guān)資料,需要的朋友可以參考下
    2023-04-04
  • Apache?IoTDB開發(fā)系統(tǒng)之Go原生接口方法

    Apache?IoTDB開發(fā)系統(tǒng)之Go原生接口方法

    這篇文章主要為大家介紹了?Apache?IoTDB開發(fā)系統(tǒng)之Go原生接口方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • Golang interface{}的具體使用

    Golang interface{}的具體使用

    interface{}是Go中可以表示任意類型的空接口,本文主要介紹了Golang interface{}的具體使用,具有一定的參考價(jià)值,感興趣的可以了解一下
    2025-05-05
  • Go 字符串格式化的實(shí)例代碼詳解

    Go 字符串格式化的實(shí)例代碼詳解

    這篇文章主要介紹了Go 字符串格式化的實(shí)例代碼詳解,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-02-02
  • Go單元測(cè)試工具gomonkey的使用

    Go單元測(cè)試工具gomonkey的使用

    本文主要介紹了Go單元測(cè)試工具gomonkey的使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • golang使用swagger的過程詳解

    golang使用swagger的過程詳解

    這篇文章主要介紹了golang使用swagger的過程詳解,本文給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2024-06-06
  • Go?defer?去掉閉包函數(shù)及用法分析

    Go?defer?去掉閉包函數(shù)及用法分析

    這篇文章主要為大家介紹了Go?defer?去掉閉包函數(shù)及用法分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • Go中JSON解析時(shí)tag的使用

    Go中JSON解析時(shí)tag的使用

    本文主要介紹了Go中JSON解析時(shí)tag的使用,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • golang實(shí)現(xiàn)簡(jiǎn)單的udp協(xié)議服務(wù)端與客戶端示例

    golang實(shí)現(xiàn)簡(jiǎn)單的udp協(xié)議服務(wù)端與客戶端示例

    這篇文章主要介紹了golang實(shí)現(xiàn)簡(jiǎn)單的udp協(xié)議服務(wù)端與客戶端,結(jié)合實(shí)例形式分析了基于UDP協(xié)議的數(shù)據(jù)傳輸相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2016-07-07
  • 詳解golang中接口使用的最佳時(shí)機(jī)

    詳解golang中接口使用的最佳時(shí)機(jī)

    接口在系統(tǒng)設(shè)計(jì)中,以及代碼重構(gòu)優(yōu)化中,是一個(gè)不可或缺的工具,能夠幫助我們寫出可擴(kuò)展,可維護(hù)性更強(qiáng)的程序,本文主要為大家介紹一下golang中接口使用的最佳時(shí)機(jī),有興趣的可以了解下
    2023-09-09

最新評(píng)論