如何在浏览器中显示大量 websocket 消息?

Posted

技术标签:

【中文标题】如何在浏览器中显示大量 websocket 消息?【英文标题】:How can I display a large number of websocket messages in a browser? 【发布时间】:2019-07-29 09:43:46 【问题描述】:

我在一个项目中工作,我正在构建一个 Web 应用程序,该应用程序从日志文件中读取任务并将数据作为 websocket 消息发送到浏览器。我将 Django 用作服务器。当我想在浏览器中显示所有消息时遇到问题。由于大量消息,浏览器变得无响应。要在浏览器中显示消息,我使用 .innerhtml

这是我的代码:

接受消息的函数:

    socket.onmessage = (e) => 
        let consoleOutput = document.getElementById("console-output");
        consoleOutput.innerHTML += e.data + "<br>";
        console.log("message", e);
    ;

发送消息的函数:

    def websocket_receive(self, event):
        response = json.loads(event["text"])
        app_name = response.get("app_name")
        path_to_logs_file = f"pathlib.Path.home()/logs/app_name/file.log"
        process = subprocess.Popen(["tail", "-f", path_to_logs_file],
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE,
                                   )
        start_time = datetime.datetime.now()
        while True:
            decoded_line = process.stdout.readline().decode("utf-8")
            if decoded_line == '' and process.poll() is not None:
                self.send(
                    "type": "websocket.close"
                )
                break
            else:
                self.send(
                    "type": "websocket.send",
                    "text": str(decoded_line).strip()
                )

如何加快向元素追加数据的速度?我将不胜感激任何有用的建议。

【问题讨论】:

consoleOutput.innerHTML += 这是不断连接一个字符串,然后导致 DOM 重新渲染,.. 你会发现使用 document.createElement("div") 会更好,然后使用 appendChild。或者,如果您只想要没有div 的文本,请使用createTextNode 【参考方案1】:

查看您的问题,您似乎想使用 websockets 来显示日志。

一段时间后,不断地追加到 innerHTML 变得非常低效。

所以你可能想要做的是直接访问 DOM..

下面是一个例子,它只是显示了当前时间 ins ms,并在一段时间后修剪旧条目以防止内存增长。

const cd = document.querySelector("code");

setInterval(() => 
  const txt = document.createTextNode(
    `Current Time in ms: $Date.now()\n`);
  cd.appendChild(txt);
  if (cd.childNodes.length > 500) cd.childNodes[0].remove();
, 10);
body 
  background-color: black;
  color: white;

code 
  white-space: pre;
&lt;code&gt;&lt;/code&gt;

【讨论】:

它工作得更快,但现在我有一个问题,当 websocket 不发送消息时,它不会停止显示数据,而是开始非常快速地显示旧消息。 @MihaelWaschl 你还在使用setInterval吗,因为那只是为了测试目的,你只需要将appendChild等放入你的onmessage.. 是的,我忘了删除它。谢谢它解决了我的问题。

以上是关于如何在浏览器中显示大量 websocket 消息?的主要内容,如果未能解决你的问题,请参考以下文章

Chrome 性能时间线在大型 websocket 消息事件后显示大型“其他”部分

如何限制龙卷风 websocket 消息大小

与使用 WebSockets 发送大量消息相比,发送大量消息是不是有很多开销?

php是如何实现websocket实时消息推送的

WebSocket

如何在 NodeJS 中显示 Websocket 对浏览器的响应