Я пытаюсь создать систему уведомлений в реальном времени для пользователей, использующих события, отправленные сервером, в python.
Проблема, с которой я сталкиваюсь, связана с обновлением sh браузера, который означает, что браузер затем попытается снова обратиться к URL-адресу EventSource, и в соответствии с документацией он должен отправить event.lastEventId как часть заголовков в следующем запросе. Я получаю None каждый раз, когда я обновляю sh страницу.
<!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
Теперь, как за каждый do c в SSE, когда клиент повторно подключается или обновляет страницу, он отправляет идентификатор последнего события в заголовках. Я пытаюсь прочитать его с помощью request.headers.get ('last-event-id'), но это всегда значение null.
Любые указатели на то, как получить последний идентификатор события, были бы полезны. Кроме того, как мне убедиться, что я не отправляю те же события даже позже, когда пользователь увидит эти события, так как все мои логи c будут основаны на последнем идентификаторе события, полученном сервером, так что если его Ни один после чтения событий с Id с 1 по 4, как бы я убедился на сервере, что я не должен отправлять их обратно, даже если last-event-id является нулевым для пользователя
.
Добавление снимков браузера
1st pi c показывает, что события принимаются браузером. например, {alpha: ab c, id: 4}
2nd pi c показывает, что полученное событие правильно устанавливает lastEventId.