簡體   English   中英

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

[英]How to stop socket.io emit from firing more then once

我目前正在使用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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM