2015-04-23 86 views
3

我想知道如何在一個名稱空間中共享套接字中設置的數據並在另一個名稱空間上訪問它?Socket.io在名稱空間之間共享套接字數據

我完全知道我可以將數據附加到套接字對象本身。當我將數據附加到一個名稱空間並嘗試在另一個名稱空間上訪問它時,會出現問題。

下面說明問題

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

module.exports.init = function(server) { 

    io = io.listen(server); 

    io.of('/chatSystem').on('connection', function(socket) { 
     /*handling set nickname event*/ 
     socket.on('set.name', function(data) { 
      /*attach nickname key to this socket*/ 
      socket.nickname = data.name; 
      socket.broadcast.emit('user.entered', data); 
     }); 
    }); 

    io.of('/chatUser').on('connection', function(socket) { 
     /*handling client event socket.send*/ 
     socket.on('message', function(data) { 
      data = JSON.parse(data); 
      data.nickname = socket.nickname; // <--- this is undefined 

      /*send to all connected client(broadcast will not send message to socket that created the message)*/ 
      socket.broadcast.send(JSON.stringify(data)); 
      data.type = 'myMessage'; 

      /*manually send back the message to the socket that created the message*/ 
      socket.send(JSON.stringify(data)); 
     }); 
    }); 
}; 

是有辦法解決這一問題?

+1

我面臨同樣的問題。當試圖在另一個命名空間中讀取時,在一個名稱命名空間中設置的名稱未定義。 如果所有的消息都只使用一個套接字'io.on('connection',function(){.....})'這個工作正常。但不能使用兩個不同的名稱空間。 –

+0

我面臨同樣的問題,並希望對此有一個答案。 –

回答

1

更新我的回答更通用的和「更安全」的解決方案

事實證明,我們可以跨命名空間共享數據,但我們必須從一次提到的Socket實例做命名空間到另一個。

假設有兩個命名空間,即namespace_Anamespace_B

要從內namespace_B得到namepsace_A相應插座對象,我們取它通過在使用當前插座對象的ID(因爲這將是相似的)從連接對象namespace_A命名空間對象。

雖然這仍然是一種解決方法,但這是迄今爲止我能夠在名稱空間之間共享會話數據的最好和最安全的方式。

我們將使用socket.id來引用所需的套接字。 這些ID看起來像這樣:/namespace#vCpuzzUi4RI1DHqfAAAH。 名稱空間內的每個套接字實例的ID都相似,但名稱空間部分(即,即,對於namespace_A,ID將類似於/namespace_A#vCpuzzUi4RI1DHqfAAAH,對於命名空間_B將是/namespace_B#vCpuzzUi4RI1DHqfAAAH。因此,如果我們可以生成類似於當前套接字的套接字ID並使用它,我們可以在另一個名稱空間中引用一個套接字實例。

,我們需要做的是首先聲明一個變量在一開始喜歡什麼:

var self = this; 

這是用來抱到本對象的引用。一個命名空間中 接下來,假設namespace_A,我們在寫這個代碼需要從namespace_B的Socket實例數據:

ns_b_socket = self.namespace_B.connected['/namespace_B#' + buildSocketID(socket.id)]; 

我們使用self.namespace_B,然後調用指本實例的namespace_B連接。連接

命名空間#:對象連接到該命名空間由 ID索引的Socket對象

哈希。

我使用自定義函數來生成ID。現在

function buildSocketID(iden) { 
    return iden.split('#')[1]; 
} 

,如果從namespace_Ans_b_socket.username,你會得到namespace_Bsocket.username設置的值。

注意:這適用於版本1.0.x及以上。對於低於此的版本,請參閱here

2

這可能有點晚,但我只是偶然找到一個更簡單的解決方案,並認爲我會分享給未來的調查人員。

套接字> 1.0,則可以將共享數據存儲在套接字的客戶端對象中。它似乎依然插座

之間共享使用上述

/* attach nickname key to this socket */ 
    socket.client.nickname = data.name; 
    /* In typescript with @types/socket.io */ 
    socket.client["nickname"] = data.name; 

和檢索

data.nickname = socket.client.nickname; 
    /* In typescript with @types/socket.io */ 
    data.name = socket.client["nickname"]; 

希望你們的榜樣這可以幫助別人了。我一直試圖找到一個解決方案,並在這個線程偶然發現。一小時後,我找到了這個選擇。

0

嗨我想到了一個workround。觀看

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

module.exports.init =函數(服務器){

/** 
    * Hi This is where things, get tricky now. 
    * statement of Problem: Am trying to send message between two namespaces. 
    * first made individual namespace socket global, 
    * And create a function that will utilized these global sockets as their second arguments 
    * and make calls to them 
    */ 

io = io.listen(server); 
var chatSystemPresentSocket; // making it Global 
var chatUserPresentSocket; //making it Global 

io.of('/chatSystem').on('connection', function(socket) { 
    /*handling set nickname event*/ 
    socket.on('set.name', function(data) { 
     /*attach nickname key to this socket*/ 
     //socket Global for the moment. 
     chatSystemPresentSocket = socket; 

     sendtochatSystem(data) // function calls 
     socket.nickname = data.name; 
     socket.broadcast.emit('user.entered', data); 
    }); 
}); 

io.of('/chatUser').on('connection', function(socket) { 
    /*handling client event socket.send*/ 
    socket.on('message', function(data) { 
     /* make socket global for the moment.*/ 
     chatUserPresentSocket = socket; 
     sendtochatSystem(data); 
     data = JSON.parse(data); 
     data.nickname = socket.nickname; // <--- this is undefined 

     /*send to all connected client(broadcast will not send message to socket that created the message)*/ 
     socket.broadcast.send(JSON.stringify(data)); 
     data.type = 'myMessage'; 

     /*manually send back the message to the socket that created the message*/ 
     socket.send(JSON.stringify(data)); 
    }); 
}); 

//Make a function to use one of the global sockets of one of the namespaces 
function sendToChatUser(data, chatUserPresentSocket){ 
chatUserPresentSocket.emit('your event', data) 
} 

function sendToChatSystem(data, chatSystemPresentSocket){ 
chatSystemPresentSocket.emit('your event', data) 
} 

};

測試一下,如果它不適合您,請在我的代碼中編輯