go 实现sse
package chat
import (
"encoding/json"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/rest/httpx"
"log"
"net/http"
"X/common/response"
"X/common/util"
"X/internal/logic/frontend/chat"
"X/internal/svc"
"X/internal/types"
"github.com/r3labs/sse/v2"
)
func SendSSEMessage(server *sse.Server, s, messageId, kfId, streamId string, baseInfo any) {
var (
state int64
relationId string
)
if baseInfo != nil {
switch d := baseInfo.(type) {
case *types.ChatResponse:
state = d.State
relationId = d.RelationId
case *types.EnquireResponse:
state = d.State
relationId = d.RelationId
case *types.PracticeResponse:
state = d.State
relationId = d.RelationId
default:
log.Println("Unsupported type:", d)
}
}
returnMessage, _ := json.Marshal(types.ChatSseResponse{
Message: s,
State: state,
RelationId: relationId,
})
server.Publish(streamId, &sse.Event{
Data: returnMessage,
})
}
func ChatSseHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
logger := logx.WithContext(r.Context())
streamId := r.URL.Query().Get("stream")
if streamId == "" {
logger.Errorf("stream is empty ")
return
}
server := sse.New()
server.CreateStream(streamId)
var req types.ChatSseRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := chat.NewChatSseLogic(r.Context(), svcCtx)
channel := make(chan string, 50)
baseInfoCh := make(chan any, 1)
go func() {
server.ServeHTTP(w, r)
}()
go func() {
defer func() {
close(channel)
close(baseInfoCh)
}()
res := &types.ChatSseResponse{}
var errChat error
res, errChat = l.ChatSse(&req, channel, baseInfoCh)
if errChat != nil {
logger.Error("ChatSseHandler error:", errChat)
}
res.ErrorMessage = response.GetErrorMessage(errChat)
returnMessage, _ := json.Marshal(res)
server.Publish(streamId, &sse.Event{
Data: returnMessage,
})
}()
baseInfo := <-baseInfoCh
var rs []rune
length := 4
for {
s, ok := <-channel
if !ok {
if len(rs) > 0 {
SendSSEMessage(server, string(rs), req.MessageId, req.OpenKfID, streamId, baseInfo)
rs = []rune{}
}
break
}
rs = append(rs, []rune(s)...)
if len(rs) > length {
SendSSEMessage(server, string(rs), req.MessageId, req.OpenKfID, streamId, baseInfo)
rs = []rune{}
if length < 4 {
length++
}
}
}
}
}
go 实现sse的更多相关文章
- SSE指令集学习:Compiler Intrinsic
大多数的函数是在库中,Intrinsic Function却内嵌在编译器中(built in to the compiler). 1. Intrinsic Function Intrinsic Fun ...
- SSE指令集优化学习:双线性插值
对SSE的学习总算迈出了第一步,用2天时间对双线性插值的代码进行了优化,现将实现的过程梳理以下,算是对这段学习的一个总结. 1. 什么是SSE 说到SSE,首先要弄清楚的一个概念是SIMD(单指令多数 ...
- Web端即时通讯技术盘点:短轮询、Comet、Websocket、SSE
1. 前言 Web端即时通讯技术因受限于浏览器的设计限制,一直以来实现起来并不容易,主流的Web端即时通讯方案大致有4种:传统Ajax短轮询.Comet技术.WebSocket技术.SSE(Serve ...
- 【HTML5】浅析html使用SSE(Server-Sent Events)连接JSP
目录结构: // contents structure [-] 关于SSE的一些话 什么是SSE SSE的浏览器支持情况 SSE的工作机制 使用SSE连接JSP文件 HTMl页面 服务器端 错误 错误 ...
- Comet、SSE、技术
1.概念: 利用长时间保留的HTTP请求(‘挂起的GET’)来让服务器向浏览器推送数据的技术,经常被称为Comet. SSE让服务器可以向客户端流式发送文本消息,比如服务器上生成的实时通知或更新.
- SSE:服务器发送事件,使用长链接进行通讯
概述 传统的网页都是浏览器向服务器“查询”数据,但是很多场合,最有效的方式是服务器向浏览器“发送”数据.比如,每当收到新的电子邮件,服务器就向浏览器发送一个“通知”,这要比浏览器按时向服务器查询(po ...
- SSE技术详解:一种全新的HTML5服务器推送事件技术
前言 一般来说,Web端即时通讯技术因受限于浏览器的设计限制,一直以来实现起来并不容易,主流的Web端即时通讯方案大致有4种:传统Ajax短轮询.Comet技术.WebSocket技术.SSE(Ser ...
- 【转】【SSE】基于SSE指令集的程序设计简介
基于SSE指令集的程序设计简介 作者:Alex Farber 出处:http://www.codeproject.com/cpp/sseintro.asp SSE技术简介 Intel公司的单指令多数据 ...
- 【转】【SEE】基于SSE指令集的程序设计简介
SSE技术简介 Intel公司的单指令多数据流式扩展(SSE,Streaming SIMD Extensions)技术能够有效增强CPU浮点运算的能力.Visual Studio .NET 2003提 ...
- SSE入门
此文主要内容来自这篇文章,本文翻译只求能理解,不求逐句翻译. 正文: 我们将在本文中介绍如何在C++/C中使用SSE指令.我的目的不是用SSE写尽可能快的程序,而是试图讲明白它的使用方法. 什么是SS ...
随机推荐
- 【Linux】Re02
一.运行启动级别 0 关机 1 单用户 2 多用户状态没有网络服务 3 多用户状态存在网络服务 4 系统未使用保留给用户 5 图形界面 6 重启 命令: init [0 - 6] 图形化界面级别需要对 ...
- 如何理解计算机类论文、机器学习论文、人工智能AI论文中的“soft”和“hard”呢?
如何理解计算机类论文.机器学习论文.人工智能AI论文中的"soft"和"hard"呢? 最近在看论文中总看到带有"soft"和"h ...
- 图床、云对象存储、CDN业务:“自定义 CDN 加速域名” 与 “自定义源站域名” 的区别
参考: https://developer.qiniu.com/kodo/8622/dev-the-binding-source-domain-name ----------------------- ...
- 如何利用HMMER鉴定基因家族成员
通常我们用的都是通过blast比对来确定我们需要的家族成员,首先是比对序列,再次是需要目标物种的蛋白序列,来进行比对,通常比对的时候我们都需要设定e-value值.今天我们来学习一下利用HMMER来鉴 ...
- 位移运算符 1<<4
转载自 https://www.cnblogs.com/ljangle/p/13036992.html 位运算 1 << 4 static final int DEFAULT_INIT ...
- SMU Summer 2024 Contest Round 6
SMU Summer 2024 Contest Round 6 Many Formulas 题意 给你一个数,你可以在这个数的任意位之间插入零个或多个+号,形成一个算式,你需要计算所有可能形成的算式的 ...
- 开发一个MutatingWebhook
介绍 Webhook就是一种HTTP回调,用于在某种情况下执行某些动作,Webhook不是K8S独有的,很多场景下都可以进行Webhook,比如在提交完代码后调用一个Webhook自动构建docker ...
- WPF 模仿前端大佬写一个Hover效果
先看一下效果吧: 原博主的地址:[动画进阶]神奇的卡片 Hover 效果与 Blur 的特性探究 - ChokCoco - 博客园 (cnblogs.com) 原效果是一个css效果,我们采用WPF的 ...
- Linux 常见编辑器
命令行编辑器 Vim Linux 上最出名的编辑器当属 Vim 了.Vim 由 Vi 发展而来,Vim 的名字意指 Vi IMproved,表示 Vi 的升级版.Vim 对于新手来说使用比较复杂,不过 ...
- 使用 Portainer CE 管理远程主机的 Docker
Prerequisites 你已经在本地主机安装了 Portainer CE 安装 打开本地主机的 Portainer CE 界面,默认地址为 localhost:9443 在左侧边栏中找到 Envi ...