2013-08-21 33 views
4

我有以下代碼服務器端。如何處理未知的socket.io事件

var io = require('socket.io').listen(8080); 

io.sockets.on('connection', function (socket) { 
    socket.on('event', function(data){ 
    // process... 
    }); 
}); 

客戶端(部分)

socket.emit('event', {type:'command', data:'data....'}); 
for (var i=0; i<=9999999; i++){ 
    socket.emit('unknownEvent', {'type':'attack', data:'a34tagfa3wtasfd'}); 
} 

現在,如何處理和防禦 'unknownEvent' 事件......?..

+0

wt do你的意思是未知的事件..如果你在客戶端意味着在服務器端發出事件你可以通過socket.on('urEventName',urFun)處理該事件; – sachin

+2

如果沒有爲該特定事件註冊事件處理程序,則服務器上不會發生任何事件。 收到請求後,事件發送器嘗試查看是否有註冊此事件的處理程序。 如果找不到,它只是返回。 – Chandu

+0

'未知'事件大規模上升,我想斷開那個套接字。海量的請求(包括空事件)是沉重的服務器負載...我害怕客戶端的惡意攻擊。 – waitfor

回答

2

老問題,但遇到了類似的事情,所以我想我會分享一種方式來做到這一點。

客戶端

所以客戶端而不是傳遞的事件,以發出的第一個參數上,使用一個通用的事件名稱,如event什麼的。我最終使用的應用程序的名稱,因爲它是短暫的。然後在數據對象中,傳入要調用的函數的名稱。

所以這個:

socket.emit('awesomeSocketEvent', {hello: 'world'}); 

變爲:

socket.emit('genericEvent', {event:'awesomeSocketEvent', hello:'world'}); 

在客戶端上重寫一切很爛,和我的客戶東西是大多隻是emit -ing所以我包裹socket.io客戶端另一個有自己發射事件的對象在事件名稱和數據對象中做了更改。

服務器端

現在在服務器端有永遠只能將是一個自定義事件稱爲,genericEvent,所以自定義事件需要被重組爲對象的屬性。一旦發生這種情況,可以通過簡單的檢查來查看事件是否存在於對象中,如果是,則調用它,如果不存在,則執行其他操作。

io.sockets.on('connection', function (socket) { 

    var events = { 
     awesomeSocketEvent: function(data){ 
      // do your socket stuff here 
     } 
    }; 

    socket.on('genericEvent', function(data){ 
     if(data.event in events){ 
      events[data.event](data); 
     } else { 
      // do your unknown event stuff here 
     } 
    }); 

}); 

在編寫該部分時查看代碼後,我不確定在connect事件中聲明瞭事件對象的性能。在連接事件之外聲明events可能會更好,然後將socket傳遞給您的所有函數。

-1

如果客戶端或服務器端Socket.io沒有該事件的註冊處理程序,那麼它不會處理它,這意味着它將返回並執行任何操作。

但是,如果客戶端向服務器發送了未註冊的事件,則您可以在客戶端或服務器端對接收到的每條消息始終使用message事件。

socket.on('message',function(m){console.log(m);}); 
+1

答案的前半部分是正確的,但關於未註冊事件的後半部分無法正常工作,因爲它們正在發送自定義事件。在v.9.13測試過,可能在v1中是一樣的。 –

0

正如Gntem所說,如果服務器端的Socket.io沒有註冊的事件處理函數,那麼事件就會返回並且沒有任何處理它。您可能會考慮使用中間件來檢查事件名稱是否有效(或者測試其他特性),如果您正在尋找更多的保護措施(例如,您期望有人用未註冊的事件向您發送垃圾郵件)。事情是這樣的:

const socketChecker = { 
    someEvent:true, 
} 

io.on('connection', function(socket) { 
    socket.use((packet, next) => { 
     if(socketChecker[packet[0]] === true){ 
      next() 
     } else { 
      //Disconnect user here 
     } 
    }); 
    socket.on('someEvent',function(){ 
     //do work here 
    }) 
}); 

請注意,如果你這樣做,你正在閱讀的是可能保留名稱的包,(如心跳,連接,信息,JSON等)。

這裏的報文的參考:我不是實際使用該 http://gevent-socketio.readthedocs.io/en/latest/packet.html

注意,所以我不知道問題可能會想出做什麼用。我剛剛查看了一些數據包中事件名稱的位置。應該找到進一步的文檔(或者應該進行更多的測試),瞭解這些數據包內實際發生的情況。