使用SSE请求大模型获取流式数据处理

背景

最近使用okhttp+SSE请求大模型接口,拿到流式数据后,刷新RecyclerView里Item布局中的TextView,使其达到逐字显示的效果。

问题

拿到流式数据后,就封装数据,并刷新RecyclerView,但是发现无法实现既定效果。

解决方案

使用队列LinkedList保存流式返回的所有数据,然后利用递归的方式,逐个从队列里取数据并刷新RecyclerView

//一些核心代码

// 缓存收到的字符
private Queue<String> charQueue = new LinkedList<>();
private List<Message> messageList = new ArrayList<>();

private void displayCharacter() {
        nextChar = charQueue.poll();
        if (nextChar == null) {
           //完成显示
           return;
        }
        
        // 显示字符
        if (messageList.isEmpty()) {
            messageList.add(new Message(nextChar));
            adapter.notifyDataSetChanged();
        } else {
            // 更新最后一条消息
            Message lastMessage = messageList.get(messageList.size() - 1);
            lastMessage.appendContent(nextChar);
            // 使用增量更新通知适配器
            adapter.notifyItemChanged(messageList.size() - 1, "typing");
        }
        
        // 滚动到底部,但不使用平滑滚动以避免干扰打字动画
        recyclerView.scrollToPosition(messageList.size() - 1);
        
        // 计算下一个字符的延迟
        int delay = calculateDelay(nextChar);
        
        // 安排显示下一个字符
        handler.postDelayed(this::displayNextCharacter, delay);
    }

后记:如果流式数据返回内容过多,等数据返回完以后再进行展示,体验效果会比较差,后来尝试了一下,在非主线程保存数据到阻塞队列里,同时开启一个单线程取数据,然后交给主线程去刷新列表进行展示,最终效果还不错

### 如何使用 SSE 实现大模型流式输出的实时传输 #### Flask 后端配置 为了实现实时的数据传输,Flask 可以利用 `flask-sse` 包来简化 Server-Sent Events (SSE) 的实现过程[^1]。下面是一个简单的例子展示如何设置一个基本的服务: ```python from flask import Flask, Response import time app = Flask(__name__) @app.route('/stream') def stream(): def event_stream(): while True: # 这里模拟从大模型获取数据的过程 yield f"data: {time.strftime('%Y-%m-%d %H:%M:%S')}\n\n" time.sleep(1) headers = { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive' } return Response(event_stream(), headers=headers) if __name__ == '__main__': app.run(threaded=True) ``` 这段代码展示了如何创建一个持续向客户端推送时间戳更新的服务。 #### 前端处理逻辑 对于前端部分来说,由于 SSE 使用的是标准 HTTP 协议,并且拥有较好的浏览器兼容性和简易的数据解析方式[^2],因此只需要几行 JavaScript 就能完成上述服务的连接并接收消息: ```javascript const evtSource = new EventSource("/stream"); evtSource.onmessage = function(event) { console.log(`New message from server at ${event.data}`); }; ``` 此段脚本会在每次接收到新的事件时打印出最新的时间戳信息至控制台。 #### 微信小程序中的解决方案 考虑到微信小程序本身的局限性——即它并不直接支持 SSE 流式请求[^3],所以如果目标平台是微信小程序,则可能需要考虑其他替代方案,如 WebSocket 或者通过 webview 组件加载外部页面的方式来间接达到同样的效果。 #### Spring Boot 集成 SSE 示例 当涉及到更复杂的企业级应用开发环境,例如采用 Spring Boot 构建的应用程序时,也可以很方便地集成 SSE 功能[^4]。需要注意的是,在实际部署过程中要妥善管理 session 和 token 解密等问题,确保系统的安全性和稳定性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值