如何停止socket.io发射多次一次

我目前正在使用node.js和socket.io在线制作一个RPG。 一切正常,直到我开始制造碰撞检测系统。 我在网上查找解决scheme,发现有类似的问题,但不明白如何解决我的问题的人。 以下是我的代码。

客户端:

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

在服务器端发射总是发送真正的坐标是在一个固定的点,我这样做,以帮助debugging。 你也可能会发现现在还没有被使用的代码,我将在未来使用它,但是我想先解决这个问题。

我的实际问题是,当我第一次移动angular色的时候,一切正常,但是第二步先做第一步,然后再做第二步,第三步做第一,二,三步。 当我移动了精灵10次之后,在步骤10之前重复了前9个步骤,并且它正在遍布屏幕。

我曾尝试通过更改代码并在任何地方添加console.log来自己find解决scheme。 我发现,如果我在服务器端发出[true,x]并且适当地修复了客户端,精灵将以我想要的方向移动,但n次是n ,这是我尝试的移动次数(1代表第一次移动,第四次向同一方向移动4次)。 刷新确实使所有事情都恢复正常。 我也尝试在函数之外移动io.connect('/ collision'),但是这也不起作用。 看来问题是服务器端的发射是保持已发送的历史数据的历史,然后每次发出呼叫时重新发送。 也可能是导致错误的客户端碰撞。

此外,在服务器端,它所做的是检查数据库是否可以移动到问题瓷砖,如果是,则为true,如果不是,则为false。 由于错误,它被设置为真。 当错误消失时,我将完成服务器端代码。

你的问题是,每次你调用move_character(x) ,你都会创build一个新的socket.io连接与它相关的事件处理程序。 所以,第一次调用它时,它会连接并设置一个事件处理程序,并emit('detection', x) ,然后设置一个事件处理程序来侦听响应。

第二次调用move_character(x) ,创build另一个socket.io连接并执行相同操作。 现在,当你的服务器得到这个消息时,它做了一些数据库工作,然后把响应广播给所有连接的套接字。 所以,现在你在同一个浏览器窗口中有两个socket.io连接,每个连接都会得到响应,并被多次处理。

第三次,你又build立了另一个,等等…


为了解决这个问题,如果你创build了一个socket.io连接,那么socket.io就可以发挥最好的效果,然后将它用于所有与这个命名空间的通信。 所以,移动你的move_character(x)函数以外的socket.io连接的创build和事件处理程序的添加,这样只会发生一次。

而在服务器上,我不太明白为什么你的数据库工作后,所有连接的客户端广播响应。 我想你会想只响应发送查询的连接。 你可以通过改变:

 collision.emit('col', true); 

 socket.emit('col', true);