2011-12-11 15 views
8

ソケットIDがio.sockets.on( 'connect')関数内に直接格納されている場合にのみ、ユーザーにメッセージを送信するように見えます。それは動作しませんなぜ彼らがログインした後、そのソケットIDを保存しようとしたとき、私は知らないsocket.idを介してクライアントにメッセージを送信

ワーキング:

が機能していない:

var clients = {}; 
    /** A new socket connection has been accepted */ 
    io.sockets.on('connection', function (socket) 
    { 
    //Used to access session id 
    var hs = socket.handshake;    
     clients[socket.id] = socket; // add the client data to the hash    

    socket.on('user-login', function(user){   
     if(!users['brownj2']){ 
     users['brownj2'] = socket.id; // connected user with its socket.id 
     } 
    }) 

    socket.on('page-load', function(pid) 
    { 
     if(users['brownj2']) 
     {   
     clients[users['brownj2']].emit('hello'); 
     } 
     else 
     { 
     console.log("NOT FOUND BROWNJ2"); 
     } 
    } 
    } 

JavaScriptクライアント側コードスニペット

var socket = io.connect(''); 
socket.on("hello", function(){ 
    alert("Hi Jack"); 
    console.log("WEBSOCKET RECIEVED"); 
}) 

ソリューション:おかげで( '接続')私は、ログインページからsocket.ioへの参照を削除し、io.sockets.onに以下を追加しなければならなかった を@alessioalex

var hs = socket.handshake; 

sessionStore.get(hs.sessionID, function(err, session){ 
    console.log("SESSION: " + util.inspect(session)); 

    clients[socket.id] = socket; // add the client data to the hash 
    validUsers[session.username] = socket.id; // connected user with its socket.id 
}) 

答えて

25

あなたのコードにはいくつかの問題があります。まず、Socket.IOを介してユーザーを認証すべきではないので、認証後に接続できることを確認する必要があります。あなたはExpressを使用している場合は、次の記事はあなたに多くを助けることができる:それは内部でSocket.IOの一部であり、変更される可能性があるためhttp://www.danielbaulig.de/socket-ioexpress/

また、あなたは、そのようなメッセージを送る回避する必要があります。

io.sockets.socket(id).emit('hello'); 

代わりに(あなたが特定のクライアントにメッセージを送信する場合)、それが接続されたクライアントと、たとえばオブジェクトを保持(一度切断されたクライアントを削除)する方が良いでしょう:

// the clients hash stores the sockets 
// the users hash stores the username of the connected user and its socket.id 
io.sockets.on('connection', function (socket) { 
    // get the handshake and the session object 
    var hs = socket.handshake; 
    users[hs.session.username] = socket.id; // connected user with its socket.id 
    clients[socket.id] = socket; // add the client data to the hash 
    ... 
    socket.on('disconnect', function() { 
    delete clients[socket.id]; // remove the client from the array 
    delete users[hs.session.username]; // remove connected user & socket.id 
    }); 
} 

// we want at some point to send a message to user 'alex' 
if (users['alex']) { 
    // we get the socket.id for the user alex 
    // and with that we can sent him a message using his socket (stored in clients) 
    clients[users['alex']].emit("Hello Alex, how've you been"); 
} 

確かに、io.sockets.socket(id)が働くこと(のdidn '実際にテストします)、Socket.IO内部の一部として常に変更することもできますので、上記の私の解決策はより安全です。私たちはここにSocket.IOの公式の例に見ることができるようにあなたは、クライアント側のコードの中で変更することもできます

もう一つは、var socket = io.connect('http://localhost');var socket = io.connect('');です:http://socket.io/#how-to-use

+0

私は socket.on( 'ログイン'、...){ユーザーが[U] = socket.id}それは動作しませんを使用しようとするおかげで、それはしかし、動作します。私はio.sockets.on( 'connection')の中に直接ユーザーを追加するように見えます。 – Jack

+1

本当ですか? socketは変数 'above'に定義されているので、その関数でも見ることができます。 – alessioalex

+1

私はあなたに、実用的で実用的でない例を示すために質問を修正しました。私は上記の「非作業」の例でメッセージを送信できない理由を理解できません。 – Jack

2

私はこの記事が生成していることがわかります

ノート

私はセッションストレージとしてのRedisを使用しています関心のかなり多くは...だから、私はこれを実装するために使用されるコードを投稿するつもりです。セッションは、ユーザの詳細を含むHTTP要求を介して、ログインページ中に最初に設定されます。これらの詳細が有効な場合(MongoDBドキュメントに対してチェックされている場合)、セッションが作成されます。

サーバーサイドコードの作成とセッション/ソケットの除去

このコードを送信

//Auth the user 
io.set('authorization', function (data, accept) { 
    // check if there's a cookie header 
    if (data.headers.cookie) { 
    data.cookie = parseCookie(data.headers.cookie); 
    data.sessionID = data.cookie['express.sid']; 

    //Save the session store to the data object 
    data.sessionStore = sessionStore; 

    sessionStore.get(data.sessionID, function(err, session){ 
     if(err) throw err; 

     if(!session) 
     { 
     console.error("Error whilst authorizing websocket handshake"); 
     accept('Error', false); 
     } 
     else 
     { 
     console.log("AUTH USERNAME: " + session.username); 
     if(session.username){ 
      data.session = new Session(data, session); 
      accept(null, true); 
     }else { 
      accept('Invalid User', false); 
     } 
     } 
    }) 
    } else { 
    console.error("No cookie was found whilst authorizing websocket handshake"); 
    return accept('No cookie transmitted.', false); 
    } 
}); 

/** A new socket connection has been accepted */ 
io.sockets.on('connection', function (socket) 
{  
    var hs = socket.handshake; 
    if(hs.session) 
    { 
    if(hs.session.username) 
    { 
     clients[socket.id] = socket; // add the client data to the hash 
     validUsers[hs.session.username] = socket.id; // connected user with its socket.id 
    } 
    } 


    socket.on('disconnect', function() 
    { 
    delete browsing[hs.session.username]; //Remove the client from the browsing hash 
    delete clients[socket.id];   // remove the client from the array 
    delete validUsers[hs.session.username]; // remove connected user & socket.id 
    }) 
.... 
} 

サーバー側の選択メッセージは私がプロジェクトのメンバーをチームにメッセージを送ることができます。ユーザーチームは、別のユーザーチームからメッセージを受信しません。

for(var i = 0; i < project.team.length; i++) 
{ 
    if(validUsers[project.team[i].username]) 
    { 
    if(clients[validUsers[project.team[i].username]]) 
    { 
     projects.update({"_id" : projectId}, 
     {"$pull" : 
      {"stories" : {"_id" : storyId}} 
     } 
    );     
     clients[validUsers[project.team[i].username]].emit('delete-story', storyId); 
    } 
    else 
    { 
     console.error("Project team member not found"); 
    } 
    } 
} 

関連する問題