[英]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.