2014-02-28 54 views
0

我已經做了幾個使用節點JS & socket.io項目..節點+ socket.io聊天服務器..我可以錯過一些消息嗎?

在我的最後一個項目,這是建立一個聊天室一樣的功能,我下面的事情。

  1. 我渲染了一個空白框,在那裏顯示聊天消息。

  2. 然後我連接到socket.io服務器。

  3. 當連接請求發送到服務器時,我也會將該聊天室的所有舊聊天消息推送到瀏覽器。

  4. 在聊天會話過程中,如果有任何用戶一致地斷開連接(網絡故障),則在重新連接後,所有舊的聊天消息將被取回&覆蓋前面的消息。

現在,我想,是否有可能會遺漏顯示一些聊天消息。到目前爲止,我還沒有看到過這種情況。

我在想什麼,如果一個人只是在創建一個連接時發送一條消息會發生什麼。是否有可能創建的新連接不會收到消息?

對不起,如果這聽起來像一個基本問題,我無法解決這個問題!

回答

1

我當時的想法是,如果消息被某人只是在交付會發生什麼創建一個連接。是否有可能創建的新連接不會收到消息?

最終,我不這麼認爲。節點是一個單線程服務器。這兩個事件將以一個簡單的順序執行。至少在功能級別上,您的應用程序代碼絕不會以交錯的方式運行,它將同時處理新連接和新消息。

你的各種回調可能當然是相互交錯,所以你必須對此進行推理。但是一旦你進入了一個函數,它就會運行到完成,而你的代碼中的任何其他部分都不會修改任何數據。

+0

謝謝..這正是我的想法..但我很想看看別人有什麼要說的! :) – Manu

0

我認爲我們可以猜測你可以創建一個包含最後10或20個帖子的數組,並且當你再次連接它時發送。如果連接重置正常是重新加載頁面,並且您不能刪除默認幷包含最後20個帖子,或者您想保存!

+0

我不明白你的意思嗎?你能詳細點嗎? – Manu

0

Server.js

var nicknames = [] 
var old_messages = [] 

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


socket.on('nickname',function(data, callback){ 

    if (nicknames.indexOf(data) != -1){ 
     callback(false); 
    }else{ 
     callback(true); 
     nicknames.push(data); 
     socket.nickname = data; 
     io.sockets.emit('nicknames', nicknames); 

     //------------ send the old messages------------- 
        io.sockets.emit('old_messages', old_messages); 


    } 
}); 

socket.on('user message',function (data){ 

     // ------------ Update de old_message list -------------- 
      old_messages.push(socket.nickname + " - " +data); 
      if (old_messages.length > 10) 
      {var aux = old_messages.pop()} 


    io.sockets.emit('user message', { 
     nick: socket.nickname, 
     message: data 
    }); 
}); 

socket.on('disconnect', function(){ 
    if (!socket.nickname) return; 
    if (nicknames.indexOf(socket.nickname) > -1){ 
    nicknames.splice(nicknames.indexOf(socket.nickname),1); 
    } 
    io.sockets.emit('nicknames', nicknames); 
}); 
}); 

Client.js

var socket = io.connect(); 
jQuery(function ($) { 
var sendMessage= $('#send-message'); 
var nickName = $('#nickname'); 
var setNicknameForm = $('#set-nickname'); 
var firstTime = true; 

setNicknameForm.submit(function(event){ 
    event.preventDefault(); 
    socket.emit('nickname',nickName.val(),function(data){ 
     if (
      setNicknameForm.hide(); 
      sendMessage.show(); 
     } else { 
      setNicknameForm.prepend('<p> Ya esta cogido </p>'); 
     } 
    // Uptade messages 
    socket.on ('old_messages', function(data){ 
     if (firstTime){ 
      for (var i=1; i<data.length(); i++){ 
       $('#messages').append($('<p>').text(data[i])); 
      }; 
          firsTime = false; 
     }; 

    }); 

    socket.on('nicknames',function(data){ 
     $('#nicknames').empty().append($('<ul>')); 
     for(var i=0; i<data.length; i++) { 
      $('#nicknames ul').append('<li>' + data[i]); 
     } 
    }); 

    }); 
}); 

sendMessage.submit(function(event){ 
    event.preventDefault(); 
    socket.emit('user message',$('#message').val()); 
    $('#message').val(''); 

}); 

socket.on('user message',function(data){ 
    $('#messages').append($('<p>').text(data.nick+" - "+data.message)); 
}); 
+0

我還沒有要求任何代碼! :/ – Manu

1

消息在服務器端完全發送,但沒有傳送到客戶端可能會發生,如果連接丟失,而消息正在飛行。這應該是一個非常低頻率的事件,但這是可能的。

爲了排除問題,爲什麼不引入類似遞增的消息ID?

在重新連接時,客戶端會發送之前收到的最後一條聊天消息的ID,並且服務器會發送任何後續消息。

+0

是的..我也可以這樣做..現在,連接/重新連接我發送所有的消息..可以避免...有沒有機會在這種情況下跳過消息? – Manu

+0

看不出有什麼東西可以丟失在那裏。最後的消息ID是客戶端接收到的統計信息,並且未連接到服務器記錄爲已發送的內容。 – gzost

+0

我的觀點是,如果消息在重新連接發生的同時到達,會發生什麼......我希望在這種情況下不會丟失一些消息。請參閱Jason Reid的答案.. :) – Manu

相關問題