Javascript 如何阻止socket.io发射多次
我目前正在使用node.js和socket.io在线制作rpg。在我开始制作碰撞检测系统之前,一切都很顺利。我在网上寻找解决方案,发现有人有类似的问题,但不知道如何解决我的问题。下面是我的代码 客户端:Javascript 如何阻止socket.io发射多次,javascript,node.js,socket.io,Javascript,Node.js,Socket.io,我目前正在使用node.js和socket.io在线制作rpg。在我开始制作碰撞检测系统之前,一切都很顺利。我在网上寻找解决方案,发现有人有类似的问题,但不知道如何解决我的问题。下面是我的代码 客户端: function move_character(x){ //socket.io start var collision = io.connect('/collision'); collision.emit('detection', x);
function move_character(x){
//socket.io start
var collision = io.connect('/collision');
collision.emit('detection', x);
collision.on('col', function (msg) {
if(msg == true) {
if (x == 'up') {
$('#sprite').animate({'top': '-=50px'},150);
} else if (x == 'down') {
$('#sprite').animate({'top': '+=50px'},150);
} else if (x == 'left') {
$('#sprite').animate({'left': '-=50px'},150);
} else if (x == 'right') {
$('#sprite').animate({'left': '+=50px'},150);
}
}
});
//socket.io end
}
服务器端:
var collision = io.of('/collision');
collision.on('connection', function (socket) {
socket.on('detection', function (x) {
pool.getConnection(function (err, con) {
con.query('SELECT class_state FROM gmaps LIMIT 1',
function (err, result) {
if (err) throw err;
else {
var mapState = result[0].class_state.split(",");
var x_coord = 6;
var y_coord = 5;
var id = ((y_cord -1)*10)+(x_cord -1);
var index;
if(x == 'up'){
index = id-10;
}else if(x == 'down'){
index = id+10;
}else if(x == 'left'){
index = id-1;
}else if(x == 'right'){
index = id+1;
}
collision.emit('col', true);
}
});
con.release();
});
});
});
在服务器端,emit总是发送true,并且坐标位于固定点,我这样做是为了帮助调试。您可能还会发现现在没有使用的代码,我将来也会使用它,但我想先修复这个bug
我的实际问题是,当我第一次移动角色时,一切正常,但第二次移动会再次执行第一次,然后执行第二次,第三次移动会执行第一次、第二次和第三次移动。当我移动精灵10次时,它正在重复第10步之前的前9个步骤,并在整个屏幕上移动
我确实试图通过修改代码和添加console来找到解决方案。日志无处不在。我发现,如果我在服务器端发出[true,x]并适当地修复客户端,精灵将朝我想要的方向移动,但n时间数n是我尝试的移动数(第一次移动1,第四次移动4)。刷新确实会使一切恢复正常。我还尝试将io.connect('/collision')移动到函数外部,但也不起作用。问题似乎是服务器端的emit保存了过去发送的数据的历史记录,然后在每次调用时重新发送。也可能是客户端上的collision.on导致了错误
此外,在服务器端,它所做的是检查DB是否可以将所讨论的磁贴移动到,如果是,则为true,如果不是,则为false。由于该错误,它再次设置为true。当bug消失后,我将完成服务器端代码。您的问题是,每次调用
move\u character(x)
,您都会创建一个新的socket.io连接,并使用它的关联事件处理程序。因此,第一次调用它时,它连接并设置一个事件处理程序,发出('detection',x)
,然后设置一个事件处理程序来侦听响应
第二次调用move_character(x)
,您将创建另一个socket.io连接并执行相同的操作。现在,当服务器收到消息时,它会执行一些数据库工作,然后将响应广播到所有连接的套接字。因此,既然在同一浏览器窗口中有两个socket.io连接,那么每个连接都会得到响应,并且会被多次处理
第三次,你又设置了一个,等等
要修复此问题,如果您创建一个socket.io连接,然后将其用于与该名称空间的所有通信,那么socket.io工作得最好。因此,将socket.io连接的创建和事件处理程序的添加移到
move_character(x)
函数之外,使其只发生一次
在服务器上,我不太明白为什么要在数据库工作后向所有连接的客户端广播响应。我想您可能只想响应发送查询的连接。您可以通过更改以下内容来完成此操作:
collision.emit('col', true);
到
每次调用
move\u character()
,都会添加另一个socket.io连接。我最终将服务器部分更改为socket,我没有意识到两者之间存在差异,并且我将服务器中的数据更改为数组。在客户端,我去掉了函数中除emit之外的所有内容,现在它可以在您的帮助下工作。
socket.emit('col', true);