场景:我有一个 Sanic Web 服务器提供简单网站的服务。该网站基本上是一个带有 Vue 模板支持的 HTML 大型数据表格。由于表格条目每几分钟就会更改,因此数据通过 WebSocket 在更改时传递。同时大约有 2000 名用户使用。我尝试实现发布/订阅架构。
问题:我的 WebSocket 在 Sanic 处理程序返回后立即关闭。我可以在内部设置循环以保持处理程序开放。但是保持 2000 个处理程序处于打开状态听起来不太好... 另外,已打开的处理程序表现得很奇怪。一个线程或一个小线程池应该能胜任这项工作。也许我误解了 Sanic 文档,需要一些设计建议。
我尝试过的事情: - 增加超时设置的时间足够长 - 尝试在 Sanic 中使用各种其他 WebSocket 设置 - 让我的客户端 JS 在 onmessage 上返回 false(Javascript websockets closing immediately after opening) - 在传递后将 ws 引用设置为 null
Sanic Web 服务器的索引:
Sanic Web服务器的Websocket处理程序(第1版,套接字立即关闭):
Sanic Web服务器的Websocket处理程序(第二版,处理程序会阻塞其他请求处理程序)。
Sanic Web服务器的Websocket处理程序(第三版,不需要recv())。
最后两个代码片段并没有太大的区别。我添加了一个ws.recv(),并从客户端发送了一些适合的东西(例如在间隔中),然后一切正常。然后发送了css、字体和favicon。但这可能不是有意的,对吧?这应该不能很好地扩展,对吧?
总的来说,这对我来说没有太多意义。我误解了什么?
问题:我的 WebSocket 在 Sanic 处理程序返回后立即关闭。我可以在内部设置循环以保持处理程序开放。但是保持 2000 个处理程序处于打开状态听起来不太好... 另外,已打开的处理程序表现得很奇怪。一个线程或一个小线程池应该能胜任这项工作。也许我误解了 Sanic 文档,需要一些设计建议。
我尝试过的事情: - 增加超时设置的时间足够长 - 尝试在 Sanic 中使用各种其他 WebSocket 设置 - 让我的客户端 JS 在 onmessage 上返回 false(Javascript websockets closing immediately after opening) - 在传递后将 ws 引用设置为 null
Sanic Web 服务器的索引:
@app.route('/')
async def serve_index(request):
return await file(os.path.join(os.path.dirname(__file__), 'index.html'))
Index.html的JS:
var app = new Vue({
el: '#app',
data() {
manydata0: 0,
manydata1: 0,
ws: null,
}
},
methods: {
update: function (json_data) {
json = JSON.parse(json_data);
this.manydata0 = json['data0'];
this.manydata1 = json['data1'];
}
},
created: function () {
this.ws = new WebSocket('ws://' + document.domain + ':' + location.port + '/reload');
messages = document.createElement('ul');
this.ws.onmessage = function (event) {
console.log("new data")
app.update(event.data);
return false;
};
document.body.appendChild(messages);
this.ws.onclose = function (event) {
console.log("closed :(")
};
Sanic Web服务器的Websocket处理程序(第1版,套接字立即关闭):
@app.websocket('/reload')
async def feed(request, ws):
#time.sleep(42) # this causes the websocket to be created and closed on client side 42 seconds after my request
await ws.send(Path(json).read_text()) # serve initial data
connected_clients.append(ws) # subscribe to websocket list. another thread will read list entries and serve them updates
Sanic Web服务器的Websocket处理程序(第二版,处理程序会阻塞其他请求处理程序)。
@app.websocket('/reload')
async def feed(request, ws):
mod_time = 0
while True:
try:
stat = os.stat(json)
if mod_time != stat.st_mtime:
await ws.send(Path(json).read_text())
except Exception as e:
print("Exception while checking file: ", e)
# this stops the server to handle other @app.routes like css, fonts, favicon
Sanic Web服务器的Websocket处理程序(第三版,不需要recv())。
@app.websocket('/reload')
async def feed(request, ws):
mod_time = 0
while True:
try:
stat = os.stat(json)
if mod_time != stat.st_mtime:
await ws.send(Path(json).read_text())
await recv() # if the client sends from time to time all is fine
except Exception as e:
print("Exception while checking file: ", e)
最后两个代码片段并没有太大的区别。我添加了一个ws.recv(),并从客户端发送了一些适合的东西(例如在间隔中),然后一切正常。然后发送了css、字体和favicon。但这可能不是有意的,对吧?这应该不能很好地扩展,对吧?
总的来说,这对我来说没有太多意义。我误解了什么?