繁体   English   中英

如何使用 socket.io 在客户端(网络浏览器)中显示来自 node.js 服务器的实时数据?

[英]How to use socket.io to display realtime data in the client (web browser) from the node.js server?

我想在浏览器中显示实时语音到文本数据。 实时我的意思是, “当我说话时,我同时收到文本 output” 我已经使用 Google 云服务 API 在 Python 中实现了语音转文本部分。 然后我使用“子进程”在 node.js 环境中运行我的 python 程序。 直到现在一切都很好。 接下来,我想在浏览器中显示实时文本。 In another word, I want to send the real-time text output from the python (which is now running in node.js using the child process) to the web browser. 我试图用 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');
});

Above, I am first using the child process to call the python program in node.js and then I am using socket.broadcast.emit to send the text output of the python program to my client side. 客户端代码如下所示:

<!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>

上面,我想在 <p> 标签内显示来自 python 程序的实时文本 output。 问题是,我无法在 web 浏览器中获取任何内容。 我的目标是,我想在 web 浏览器中实时显示我所说的任何内容。

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

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

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

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

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

const socket = io('ws://localhost:3000');

socket.on('connect', () => {
  // do any authentication or handshaking here.
  console.log('socket connected');
});

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

根据以下评论:

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

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

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

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

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

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

我认为这就是你想要的:

//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);      
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM