【发布时间】:2020-08-12 19:07:36
【问题描述】:
我正在尝试为使用的用户构建实时通知系统 服务器在 python 中发送事件。
我面临的问题是当我刷新浏览器时,这意味着 然后浏览器将尝试再次点击 EventSource url,并按照 文档它应该将 event.lastEventId 作为下一个标题的一部分发送 要求。每次刷新页面时我都会得到无。
<!DOCTYPE html>
<html>
<header><title>SSE test</title></header>
<body>
<ul id="list"></ul>
<script>
const evtSource = new EventSource("/streams/events?token=abc");
evtSource.onmessage = function(event) {
console.log('event', event)
console.log('event.lastEventId', event.lastEventId)
const newElement = document.createElement("li");
const eventList = document.getElementById("list");
newElement.innerHTML = "message: " + event.data;
eventList.appendChild(newElement);
}
</script>
</body>
</html>
在服务器端
from sse_starlette.sse import EventSourceResponse
from asyncio.queues import Queue
from starlette.requests import Request
@event_router.get(
"/streams/events",
status_code=HTTP_200_OK,
summary='',
description='',
response_description='')
async def event_stream(request: Request):
return EventSourceResponse(send_events(request))
async def send_events(request: Request):
try:
key = request.query_params.get('token')
last_id = request.headers.get('last-event-id')
print('last_id ', last_id) # this value is always None
connection = Queue()
connections[key] = connection
while RUNNING:
next_event = await connection.get()
print('event', next_event)
yield dict(data=next_event, id=next_event['id'])
connection.task_done()
except asyncio.CancelledError as error:
pass
现在,根据 SSE 上的每个文档,当客户端重新连接或刷新 页面它将在标题中发送最后一个事件ID。我正在尝试阅读它 使用 request.headers.get('last-event-id'),但这始终为 null。
有关如何获取最后一个事件 ID 的任何指示都会有所帮助。还, 我如何确保以后不会发送相同的事件 用户已经看到了这些事件,因为我的整个逻辑将基于 服务器接收到的 last-event-id,所以如果读取后为 None Id 1 到 4 的事件,我将如何确保在服务器中我应该 即使用户的 last-event-id 为 null,也不会将这些发回
.
添加浏览器快照
第一张图片显示浏览器正在接收事件。 例如{alpha: abc, id:4}
第二张图片显示收到的事件是 正确设置 lastEventId。
【问题讨论】:
标签: javascript python server-sent-events fastapi starlette