Server-Sent Events (SSE) 技术详解

部署运行你感兴趣的模型镜像

Server-Sent Events (SSE) 技术详解

一、基础概念

1. 核心特点

  • 单向通信:仅服务器→客户端方向
  • 基于HTTP:使用标准HTTP/1.1协议
  • 文本协议:UTF-8编码的纯文本格式
  • 自动重连:内置断线重连机制
  • 轻量级:API设计简洁

2. 协议对比

特性SSEWebSocketPolling
协议HTTPws/wssHTTP
延迟极低
数据方向单向双向半双工
浏览器支持除IE全部全部

二、技术实现细节

1. HTTP 响应头

服务器必须设置以下头部:

Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive

2. 事件流格式

基本结构:

event: messageType\n
data: messageContent\n\n

示例:

event: status
data: {"time": "2023-05-20", "value": 42}

data: This is a simple message

: comment line (ignored)
id: 12345
retry: 5000

3. 字段说明

  • data: 消息内容(可多行,最终会合并)

  • event: 事件类型(默认message)

  • id: 事件ID(用于断线重连时Last-Event-ID头)

  • retry: 重连延迟(毫秒)

  • :: 注释行(会被客户端忽略)

三、实践

以下是用Python实现SSE(Server-Sent Events)的完整示例,包含服务端和客户端实现:

1、服务端

from flask import Flask, Response, request
import time
import json

app = Flask(__name__)

@app.route('/stream')
def stream():
    def event_stream():
        count = 0
        while True:
            time.sleep(1)  # 模拟延迟
            count += 1
            # 构建SSE格式数据
            data = {
                "time": time.strftime("%Y-%m-%d %H:%M:%S"),
                "count": count
            }
            # SSE格式要求
            event = f"data: {json.dumps(data)}\n\n"
            yield event
            
            if count >= 10:  # 限制发送10条后结束
                yield "event: end\ndata: Stream completed\n\n"
                break

    return Response(
        event_stream(),
        mimetype="text/event-stream",
        headers={
            'Cache-Control': 'no-cache',
            'Connection': 'keep-alive',
            'X-Accel-Buffering': 'no'  # 禁用Nginx缓冲
        }
    )

if __name__ == '__main__':
    app.run(threaded=True, port=5000)

2、客户端

import requests
import json

url = 'http://localhost:5000/stream'

def sse_client():
    with requests.get(url, stream=True) as response:
        content_type = response.headers.get('content-type', '')
        if 'text/event-stream' in content_type:
            buffer = ""
            for chunk in response.iter_content(chunk_size=1024):
                if chunk:
                    buffer += chunk.decode('utf-8')
                    while '\n\n' in buffer:
                        event, buffer = buffer.split('\n\n', 1)
                        process_event(event)
        else:
            print(f"Server does not support SSE, content-type: {content_type}")

def process_event(event):
    lines = event.split('\n')
    event_data = {}
    event_type = 'message'  # 默认事件类型
    
    for line in lines:
        if line.startswith('event:'):
            event_type = line.split(':', 1)[1].strip()
        elif line.startswith('data:'):
            data = line.split(':', 1)[1].strip()
            try:
                event_data = json.loads(data)
            except json.JSONDecodeError:
                event_data = data
    
    if event_type == 'end':
        print("Stream ended")
    else:
        print(f"Received {event_type}: {event_data}")

if __name__ == '__main__':
    sse_client()

3、关键点说明

服务端要点:
  • 使用生成器(yield)实现持续数据流

  • 响应头必须设置text/event-stream MIME类型

  • 每条消息以data: 开头,以两个换行符\n\n结束

  • 支持自定义事件类型(event: xxx)

客户端要点:
  • 使用stream=True保持长连接

  • 按块(chunk)处理响应数据

  • 正确处理消息边界(检测\n\n)

  • 解析SSE格式的各个字段

您可能感兴趣的与本文相关的镜像

Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值