![](/img/trans.png)
[英]How to send binary data from a Node.js socket.io server to a browser client?
[英]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.