【问题标题】:How to use socket.io to display realtime data in the client (web browser) from the node.js server?如何使用 socket.io 从 node.js 服务器在客户端(Web 浏览器)中显示实时数据?
【发布时间】:2021-04-27 12:58:53
【问题描述】:

我想在浏览器中显示实时语音到文本数据。我的意思是实时,“在我说话的同时,我得到了文本输出”。我已经使用 Google 云服务 API 在 Python 中实现了语音到文本的部分。然后我使用“子进程”在 node.js 环境中运行我的 python 程序。直到现在一切都很好。接下来,我想在浏览器中显示实时文本。换句话说,我想将来自 python(现在使用子进程在 node.js 中运行)的实时文本输出发送到 Web 浏览器。我试图用socket.io做到这一点。这是我的服务器端 (node.js) 代码,其中也应用了 socket.io:

const express = require('express');
//const router = express.Router();
const {spawn} = require('child_process');
const path = require('path');
const app = express();
const http = require('http');
const server = http.createServer(app);
//const server = http.createServer(app); 
const { Server } = require("socket.io");
const io = new Server(server);

function runScript(){
  return spawn('python3', [
          "-u",
    path.join(__dirname, 'script.py')
  ]);
}

const subprocess = runScript()


// print output of the script

app.get('/', (req,res) => {

        res.sendFile(__dirname + '/index.html');
});

io.on('connection', (socket) => {

subprocess.stdout.on('data', (data) => {
  //console.log(`data:${data}`);
        socket.on('message', (data) => {
                socket.broadcast.emit('message', data);
        });
});
});

server.listen(3000, () => {
  console.log('listening on *:3000');
});

上面,我首先使用子进程调用node.js中的python程序,然后我使用socket.broadcast.emit将python程序的文本输出发送到我的客户端边。客户端代码如下所示:

<!DOCTYPE html>

<html>
        <head>
        <script src="/socket.io/socket.io.js"></script>
        <script>
                var socket = io();

        var messages = document.getElementById('messages'); 

        //const EventEmitter = require('events');
        //const emitter = new EventEmitter()
        //emitter.setMaxListeners(50)
        socket.on('messages', function(data) {
                
                 document.querySelector("#style1".innerHTML = `<p>${data1}</p>`
               
        });
        </script>
        </head>

        <body id="messages">
                <h1> This is crazy </h1>
                <div id="style1">
                </div> 

        </body>

</html>

上面,我想在

标签内显示python程序的实时文本输出。 问题是,我无法在网络浏览器中获取任何内容。 我的目标是,我想在网络浏览器中实时显示我所说的任何内容。

我对 socket.io 了解不多。事实上,这是我第一次使用这项技术。

【问题讨论】:

    标签: javascript python node.js socket.io child-process


    【解决方案1】:

    您的 Node.js 服务器将充当套接字服务器。正如您的代码所示,它在端口上侦听套接字连接,并在连接时创建一个套接字,然后您也可以发送消息。通过简单粗略的审查,服务器代码看起来不错。

    在您的网页上,您正在创建套接字并监听消息。

    但是网页上运行的套接字还没有连接到服务器,这就是为什么还没有工作。

    假设你在 localhost 上执行此操作,只需将套接字服务器地址添加到它的构造函数中,然后侦听连接。

    const socket = io('ws://localhost:3000');
    
    socket.on('connect', () => {
      // do any authentication or handshaking here.
      console.log('socket connected');
    });
    

    更高级的实现应该优雅地处理关闭套接字。

    根据以下评论:

    我添加了您在上面建议的行。即使现在网页上什么也看不到,但我收到了这个警告:(节点:14016)MaxListenersExceededWarning:检测到可能的 EventEmitter 内存泄漏。添加了 11 个消息侦听器。使用emitter.setMaxListeners() 增加限制

    仔细查看您的服务器代码,我相信这是根本问题

    subprocess.stdout.on('data', (data) => {
      //console.log(`data:${data}`);
            socket.on('message', (data) => {
                    socket.broadcast.emit('message', data);
            });
    });
    });
    

    每次您从subprocess.stdout 接收数据时,都会向您的套接字添加一个新的onmessage 事件处理程序,所以一段时间后,您添加了太多事件处理程序。

    重新编写您的逻辑,以便您只添加一次socket.on('message')(通常在您创建套接字之后)。

    还值得注意的是,在上面的代码中,没有使用来自 stdout 的 data,因为 data 变量正在由您的 onmessage 函数在较低范围内重新定义。由于正在重新定义数据,因此 Python 程序的输出将被忽略。

    我想这就是你想要的:

    //echo any message you receive from the socket back to the socket
    socket.on('message', (data) => {
      socket.broadcast.emit('message', data);
    });
    
    //send data from std out to the socket.
    subprocess.stdout.on('data', (data) => {
      //console.log(`data:${data}`);
       socket.broadcast.emit('message', data);      
    });
    

    【讨论】:

    • 我添加了您上面建议的行。即使现在网页上什么也看不到,但我收到了这个警告:(node:14016) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 message listeners added. Use emitter.setMaxListeners() to increase limit 请帮帮我。谢谢,艾伦!
    • 我更新了我的答案以解决您的评论。
    • 代码现在运行良好。谢谢,艾伦!
    猜你喜欢
    • 2015-10-21
    • 2014-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-07
    • 2016-04-10
    • 2017-07-25
    相关资源
    最近更新 更多