事件源不代表每个 client/session 处的信息
Event Source doesn't represent an information at each client/session
我有一个 python 服务器端,它使用 SSE 发送请求。
这里是python代码的例子。它发送一个 'action-status' 和 JS 必须处理(要做)的数据:
async def sse_updates(request):
loop = request.app.loop
async with sse_response(request) as resp:
while True:
# Sending request for queue' token remove when it's been removed on server.
if request.app['sse_requests']['update_queue_vis_remove']:
await resp.send("update-remove")
request.app['sse_requests']['update_queue_vis_remove'] = False
# Sending request for queue' token adding up when it's been added on server.
if request.app['sse_requests']['update_queue_vis_append'][0]:
await resp.send(f"update-append {request.app['sse_requests']['update_queue_vis_append'][1]} {request.app['sse_requests']['update_queue_vis_append'][2]}")
request.app['sse_requests']['update_queue_vis_append'][0] = False
# Sending request for redundant token's list rewrite (on client side ofc)
if request.app['sse_requests']['redundant_tokens_vis'][0]:
await resp.send('update-redtokens ' + ''.join(token + ' ' for token in request.app['sse_requests']['redundant_tokens_vis'][1]))
request.app['sse_requests']['redundant_tokens_vis'][0] = False
await asyncio.sleep(0.1, loop=loop)
return resp
以及处理响应的 JS 脚本:
evtSource = new EventSource("http://" + window.location.host + "/update")
evtSource.onmessage = function(e) {
// Data from server is fetching as "<server-event-name> <data1> <data2> <data3> ..."
let fetched_data = e.data.split(' ');
// First option is when a token has been removed from server this event has to be represented on a client-side.
if(fetched_data[0] === "update-remove")
displayQueueRemove();
// The second option is when a token appended on server and also it should be represented to a user
else if(fetched_data[0] === "update-append")
// fetched_data[1] - token
// fetched_data[2] - it's (token's) position
displayQueueAdd(fetched_data[1], parseInt(fetched_data[2]));
// The last possible options is that if the web-page will has refreshed a data in redundant_tokens should be rewritten
else if (fetched_data[0] === "update-redtokens"){
fetched_data.shift();
// Creating variables for token' wrapping
let tag;
let text;
// Wrapping tokens and store it into the array.
for(let i = 0; i < fetched_data.length - 1; i++) {
tag = document.createElement("div");
text = document.createTextNode(fetched_data[i]);
tag.appendChild(text);
tag.setAttribute("class", "token-field");
redundant_tokens[i] = tag;
}
}
}
问题是,如果我打开两个或多个浏览器 windows(会话),其中唯一一个会捕获响应并表示它。此外,在某些情况下,我从一个会话发送请求,但获得对另一个会话的响应。
是否有使用 SSE 修复它的选项(我的意思是,我正在考虑其他一些方法,但我想尝试使用 SSE)?
我认为你的问题是同步数据(app["sse_requests"]
)。
根据您修改数据的方式和需要通知的人,您可能需要保留一个客户端(会话)列表。
例如,如果所有客户端都需要收到所有事件的通知,则保持 list
(或更好 set
)连接的客户端并创建周期函数(使用 create_task
) 在其中通知所有人。
如果客户端只需要收到某些事件的通知,那么您需要使用 request
对象中的某种键来识别该客户端。
我有一个 python 服务器端,它使用 SSE 发送请求。
这里是python代码的例子。它发送一个 'action-status' 和 JS 必须处理(要做)的数据:
async def sse_updates(request):
loop = request.app.loop
async with sse_response(request) as resp:
while True:
# Sending request for queue' token remove when it's been removed on server.
if request.app['sse_requests']['update_queue_vis_remove']:
await resp.send("update-remove")
request.app['sse_requests']['update_queue_vis_remove'] = False
# Sending request for queue' token adding up when it's been added on server.
if request.app['sse_requests']['update_queue_vis_append'][0]:
await resp.send(f"update-append {request.app['sse_requests']['update_queue_vis_append'][1]} {request.app['sse_requests']['update_queue_vis_append'][2]}")
request.app['sse_requests']['update_queue_vis_append'][0] = False
# Sending request for redundant token's list rewrite (on client side ofc)
if request.app['sse_requests']['redundant_tokens_vis'][0]:
await resp.send('update-redtokens ' + ''.join(token + ' ' for token in request.app['sse_requests']['redundant_tokens_vis'][1]))
request.app['sse_requests']['redundant_tokens_vis'][0] = False
await asyncio.sleep(0.1, loop=loop)
return resp
以及处理响应的 JS 脚本:
evtSource = new EventSource("http://" + window.location.host + "/update")
evtSource.onmessage = function(e) {
// Data from server is fetching as "<server-event-name> <data1> <data2> <data3> ..."
let fetched_data = e.data.split(' ');
// First option is when a token has been removed from server this event has to be represented on a client-side.
if(fetched_data[0] === "update-remove")
displayQueueRemove();
// The second option is when a token appended on server and also it should be represented to a user
else if(fetched_data[0] === "update-append")
// fetched_data[1] - token
// fetched_data[2] - it's (token's) position
displayQueueAdd(fetched_data[1], parseInt(fetched_data[2]));
// The last possible options is that if the web-page will has refreshed a data in redundant_tokens should be rewritten
else if (fetched_data[0] === "update-redtokens"){
fetched_data.shift();
// Creating variables for token' wrapping
let tag;
let text;
// Wrapping tokens and store it into the array.
for(let i = 0; i < fetched_data.length - 1; i++) {
tag = document.createElement("div");
text = document.createTextNode(fetched_data[i]);
tag.appendChild(text);
tag.setAttribute("class", "token-field");
redundant_tokens[i] = tag;
}
}
}
问题是,如果我打开两个或多个浏览器 windows(会话),其中唯一一个会捕获响应并表示它。此外,在某些情况下,我从一个会话发送请求,但获得对另一个会话的响应。 是否有使用 SSE 修复它的选项(我的意思是,我正在考虑其他一些方法,但我想尝试使用 SSE)?
我认为你的问题是同步数据(app["sse_requests"]
)。
根据您修改数据的方式和需要通知的人,您可能需要保留一个客户端(会话)列表。
例如,如果所有客户端都需要收到所有事件的通知,则保持 list
(或更好 set
)连接的客户端并创建周期函数(使用 create_task
) 在其中通知所有人。
如果客户端只需要收到某些事件的通知,那么您需要使用 request
对象中的某种键来识别该客户端。