慷慨大方的泡面 · nodejs-notes/Linux/孤儿进 ...· 1 月前 · |
成熟的脸盆 · 东风汽车股份有限公司· 2 月前 · |
没读研的油条 · CertificateExpiredExce ...· 4 月前 · |
欢乐的领带 · 严弘:中科大少年班走出来的金融教授 - ...· 4 月前 · |
帅气的鼠标 · 岗位需求多、培训重实践…电商成大学生就业新选择· 5 月前 · |
var express = require('express');
var app = express();
var server = app.listen(3000);
var replyFromBot;
app.use(express.static('public'));
var socket = require('socket.io');
var io = socket(server);
io.sockets.on('connection' , newConnection);
function newConnection(socket) {
console.log(socket.id);
listen = true;
socket.on('Quest' ,reply);
function reply(data) {
replyFromBot = bot.reply("local-user", data);
console.log(socket.id+ " "+replyFromBot);
socket.emit('Ans' , replyFromBot);
}
我使用node.js、socket.io和express创建了一个基于服务器的聊天机器人应用程序,但问题是,当我第一次调用socket.on时,它第一次被执行一次,第二次被执行两次,第三次执行三次,等等,我已经通过在我的客户端上设置一个标志来解决这个问题,这样它只能显示一次。我只想知道我的代码在逻辑上是否正确--我的意思是,这是一个好代码吗?因为如果客户端第十次提出问题,而监听器数组将有10+9+8....+1侦听器,那么它将继续增加,这取决于客户机询问的问题的数量。这不太好
我试着使用removeListener,它只删除了一次侦听器,并且第二次进行了多次调用。你们有什么建议?我是这样做的,还是有其他方法在socket.on调用时添加侦听器,在执行时删除侦听器,下次调用时再添加侦听器
谢谢你。
客户代码:
function reply() {
socket.emit('Quest' , Quest);
flag = true;
audio.play();
socket.on('Ans', function(replyFromBot) {
if(flag) {
console.log("hi");
var para = document.createElement("p2");
x = document.getElementById("MiddleBox");
para.appendChild(document.createTextNode(replyFromBot));
x.appendChild(para);
x.scrollTop = x.scrollHeight;
flag = false;
}
发布于 2018-04-12 06:05:13
问题是由您的客户端代码引起的。每次在客户端调用
reply()
函数时,都会设置一个额外的
socket.on('Ans', ...)
事件处理程序,这意味着它们会累积。您可以将其更改为
socket.once()
,每次得到
Ans
消息后,它都会自行删除。然后,还可以删除
flag
变量。
function reply() {
socket.emit('Quest' , Quest);
audio.play();
// change this to .once()
socket.once('Ans', function(replyFromBot) {
console.log("hi");
var para = document.createElement("p2");
x = document.getElementById("MiddleBox");
para.appendChild(document.createTextNode(replyFromBot));
x.appendChild(para);
x.scrollTop = x.scrollHeight;
}
Socket.io并不是真正作为请求/响应系统构建的,这正是您试图将其用作的。实现这一点的一个更好的方法是使用
capability that socket.io has
,这样您就可以直接响应您发送的
Quest
消息。
您还需要修复服务器上的共享变量
replyFromBot
和
listen
,因为一旦有多个用户使用您的服务器,这些都是等待发生的并发问题。
更好解决方案
更好的解决方案是使用
ack
功能,socket.io必须直接响应您发送的消息。要做到这一点,您可以将服务器更改为:
function newConnection(socket) {
console.log(socket.id);
socket.on('Quest', function(data, fn) {
let replyFromBot = bot.reply("local-user", data);
console.log(socket.id+ " "+replyFromBot);
// send ack response
fn(replyFromBot);
}
然后,将客户端代码更改为:
function reply() {
audio.play();
socket.emit('Quest', Quest, function(replyFromBot) {
console.log("hi");
var para = document.createElement("p2");