当前位置: 代码迷 >> JavaScript >> 如何停止socket.io发射一次以上
  详细解决方案

如何停止socket.io发射一次以上

热度:70   发布时间:2023-06-05 09:32:47.0

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

客户端:

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,并且坐标位于固定点,我这样做是为了帮助调试。 您可能还会发现目前未使用的代码,将来我会使用它,但是我想先修复此错误。

我的实际问题是,当我第一次移动角色时,一切正常,但是第二步再次执行第一步,随后进行第二步,第三步进行第一步,第二步然后是第三步。 到我将精灵移动10次时,它正在重复第10步之前的第9个步骤,并且遍及整个屏幕。

我确实尝试通过更改代码并在各处添加console.log来找到解决方案。 我发现,如果我在服务器端发出[true,x]并适当地修复客户端,则精灵将朝我想要的方向移动,但是n次,其中n是我尝试的移动次数(第1步为1 ,则4代表相同方向的第4个移动)。 刷新确实会使一切恢复正常。 我也尝试将io.connect('/ collision')移到函数之外,但这也不起作用。 看来问题出在服务器端,发射端保留了过去已发送数据的历史记录,然后在每次调用时重新发送。 也可能是客户端上的冲撞导致该错误。

同样,在服务器端,它的作用是检查数据库是否可以将所涉及的图块移至该图块,如果是,则为true,否则为false。 由于该错误,再次将其设置为true。 当错误消失后,我将完成服务器端代码。

您的问题是,每次调用move_character(x) ,都会使用与其关联的事件处理程序创建一个新的socket.io连接。 因此,第一次调用它时,它会连接并设置一个事件处理程序,执行emit('detection', x) ,然后设置一个事件处理程序以侦听响应。

第二次调用move_character(x) ,您将创建另一个socket.io连接并执行相同的操作。 现在,当服务器收到消息时,它将执行一些数据库工作,然后将响应广播到所有连接的套接字。 因此,既然您在同一个浏览器窗口中有两个socket.io连接,则每个连接都将获取响应,并且它会被处理多次。

第三次,您设置了另一个,依此类推...


要修复,如果您创建一个socket.io连接,然后将其用于与该名称空间的所有通信,则socket.io的工作效果最佳。 因此,将socket.io连接的创建和事件处理程序的添加move_character(x)函数之外,因此它只发生一次。

在服务器上,我不太了解为什么您的数据库工作后向所有连接的客户端广播响应。 我认为您只想响应发送查询的连接。 您可以通过更改以下内容来做到这一点:

collision.emit('col', true);

socket.emit('col', true);
  相关解决方案