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