【问题标题】:Restarting a JavaScript websocket when the server restarts - why does this code restart multiple websockets?服务器重新启动时重新启动 JavaScript websocket - 为什么这段代码会重新启动多个 websocket?
【发布时间】:2020-09-22 08:50:43
【问题描述】:

我正在尝试让 websocket 连接在被服务器关闭后自动重启。

当我在“http://127.0.0.1:5082/”的浏览器中打开页面时,我的示例代码有效。 websocket 计数器计数完毕,显示调试文本“消息”。

当我关闭服务器时,调试消息“关闭”出现,然后“启动/关闭”交替出现。

当我再次打开服务器时,有几十个 websocket 正在运行,并且调试消息在“消息”和“关闭”之间快速切换

如何确保一次只有一个 websocket 连接处于活动状态?

最小的例子,使用 Python 的 FastAPI 作为服务器:

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Websocket test</title>
</head>
<body>

<div id="container">
    OK - wait for websocket
</div>
<hr noshade>
<div id="debug">
    Some debug text here
</div>

<script>

    var debug_container = document.getElementById("debug")
    debug_container.innerHTML = "Debug: Javascript is running"

    function my_websocket() {
        debug_container.innerHTML = "starting"
        var ws = new WebSocket("ws://localhost:5082/ws")

        ws.addEventListener('message', function (event) {
            debug_container.innerHTML = "message"
            var container = document.getElementById("container")
            container.innerHTML = event.data
        })
        ws.addEventListener('open', function (event) {
            debug_container.innerHTML = "open"
        })
        ws.addEventListener('close', function (event) {
            debug_container.innerHTML = "close";
            setInterval(my_websocket, 5000);
        })
        ws.addEventListener('error', function (event) {
            debug_container.innerHTML = "error"
        })
    }

    my_websocket()

</script>

</body>
</html>

websocket 由 Python FastAPI 服务器提供服务

import uvicorn
import websockets
from fastapi import FastAPI, WebSocket
from fastapi.responses import HTMLResponse
from pathlib import Path
import asyncio

app = FastAPI()


@app.get('/')
def index():
    return HTMLResponse(Path("index.html").read_text())


@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
    await websocket.accept()
    cnt = 1
    while True:
        cnt += 1
        try:
            await websocket.send_text(f"{cnt}")
        except websockets.exceptions.ConnectionClosedOK:
            break
        await asyncio.sleep(0.25)

if __name__ == '__main__':
    uvicorn.run(app=app, host="0.0.0.0", port=5082)

【问题讨论】:

    标签: javascript websocket fastapi


    【解决方案1】:

    客户端建立多个websocket连接的原因是以下代码:

    ws.addEventListener('close', function (event) {
        debug_container.innerHTML = "close";
        setInterval(my_websocket, 5000);
    })
    

    使用 setInterval 会使其每 5 秒创建一个新的 websocket 连接。我认为您的意思是改用 setTimeout()。

    【讨论】:

    • 这已经改善了这种情况,但是当我关闭服务器并稍后再次打开时,我仍然可以运行多个 websocket。
    • 这个问题是我在 settimeout 上的第二个“错误”引起的,在我删除它之后,它可以工作。谢谢
    猜你喜欢
    • 2022-08-24
    • 2013-11-10
    • 2011-04-16
    • 2011-04-21
    • 2022-07-28
    • 1970-01-01
    • 2015-08-19
    • 2019-08-23
    相关资源
    最近更新 更多