2012-04-25 16 views
0

我正在通過套接字從FF附加套件寫入到java服務器。我寫了幾個請求,服務器似乎一個接一個地處理它們。相比之下,來自服務器的響應是同時處理的。如何在我的代碼中刷新套接字

我試着衝在服務器中的出流,但它什麼都不做。我不明白髮生了什麼事。

我感謝所有幫助,謝謝。

EDIT1:可能是附加(客戶端)不刷新輸入流,這可能嗎?我在java服務器中使用out.println,因此'\ n'必須刷新其輸出流,並且網絡庫使用write.flush(),但是我沒有看到任何其他刷新輸入。

EDIT2:這裏是我的代碼:

exports.main = function() { 
    try { 
     // At first, we need a nsISocketTransportService 
     var transportService = 
      Cc["@mozilla.org/network/socket-transport-service;1"] 
      .getService(Ci.nsISocketTransportService); 

     // Try to connect to localhost:2222 
     var transport = transportService.createTransport(null, 0, "localhost", 6666, null); 

     var stream = transport.openInputStream(Ci.nsITransport.OPEN_UNBUFFERED,null,null); 
     var instream = Cc["@mozilla.org/scriptableinputstream;1"] 
      .createInstance(Ci.nsIScriptableInputStream); 

     // Initialize 
     instream.init(stream); 
     var outstream = transport.openOutputStream(0, 0, 0); 



     var dataListener = { 
      onStartRequest: function(request, context){}, 

      onStopRequest: function(request, context, status){ 
       instream.close(); 
       outstream.close(); 
      }, 

      onDataAvailable: function(request, context, inputStream, offset, count) { 
       var data = instream.read(count); 
       console.log(data);    
      }, 
     }; 

     var pump = Cc["@mozilla.org/network/input-stream-pump;1"] 
       .createInstance(Ci.nsIInputStreamPump); 
     pump.init(stream, -1, -1, 0, 0, false); 
     pump.asyncRead(dataListener, null); 

     // Write data 
     console.log("hi1"); 
     var outputData = "hi1\n"; 
     outstream.write(outputData, outputData.length); 

     // Write data 
     console.log("hi2"); 
     var outputData = "hi2\n"; 
     outstream.write(outputData, outputData.length); 

    } catch (e){ 
     console.log("Error" + e.result + ": " + e.message); 
     return e; 
    } return null; 
}; 

所以,當我運行它,我得到:

Client > hi1 
Client > hi2 
Server > bye1 
Server > bye2 

它應該是:

Client > hi1 
Server > bye1 
Client > hi2 
Server > bye2 
+0

沒有代碼,沒有幫助。 – 2012-04-25 15:21:41

+0

@MarkoTopolnik:如果你想看看,我添加了一些代碼。 – synack 2012-04-25 16:09:58

+0

您將此標記爲Java,但我沒有看到您的問題與Java的任何關係。如果你沒有標記它,我們就不會有這個對話。我不是JavaScript專家。 – 2012-04-25 16:34:09

回答

0

你正在編寫同步輸出流,這意味着,當你做任何其他的JavaScript代碼可以運行。因此,在寫入時從服務器接收任何內容都是不可能的,傳入的數據只是放入緩衝區。

的另一個問題是,你不必等待來自服務器的響應發送下一個字符串。通常情況下,您可以在服務器響應到達之前發送它們兩個。只有當您收到對前一個字符串的響應時,您纔可能要發送下一個字符串。

你可能想使用發送功能,像這樣的:

Components.utils.import("resource://gre/modules/NetUtil.jsm"); 

var toSend = ["hi1\n", "hi2\n"]; 

function sendNextString(outstream) 
{ 
    if (!toSend.length) 
    return; // Nothing left to send 

    var outputData = toSend.shift(); 
    console.log(outputData); 
    var instream = Components.classes["@mozilla.org/io/string-input-stream;1"] 
          .createInstance(Components.interfaces.nsIStringInputStream); 
    instream.setData(outputData, outputData.length); 

    NetUtil.asyncCopy(instream, outstream); 
} 

而且在onDataAvailablepump.asyncRead()後,以及你會打電話sendNextString(outstream)在你的代碼。

PS:從我所知道的,沖洗流是而不是這裏的問題 - 您使用的是非緩衝流。

+0

謝謝!這幫助了我很多。儘管它並不完美,但是當我將sendNextString調用到onDataAvailable時,服務器似乎沒有收到任何信息。有些奇怪的事情正在發生,你怎麼看? (我更新了問題中的代碼) – synack 2012-04-26 13:49:33

+0

@ user1336939:我認爲你需要開始調試你的代碼 - 你應該能夠說出比「發生奇怪的事情」更多的東西。 – 2012-04-26 13:53:06

+0

但我調試服務器,並沒有收到任何東西。我怎樣才能調試附加組件?謝謝 – synack 2012-04-26 14:01:26

0

TCP是一個流協議,所以你會收到一個字節流。如果你想要數據包,你必須通過TCP實現你自己的協議,才能分離它們。這個話題在互聯網上被廣泛報道。

編輯

這是socket編程的一個常見問題。大多數人一開始並不理解TCP套接字是流,而不是消息隊列。

我的意思是,在插座的一端的一個呼叫「發送」不一定對應到另一端的一個「接收」。底層可以決定分組或分裂隨意發送的字節。

所以,你可以有這樣的事情:

  • 客戶端發送 「ABCD」
  • 客戶端發送 「EFGH」
  • 服務器接收到 「AB」
  • 服務器接收 「CDEF」
  • 服務器收到「GH」

This i這是一條流,而不是一條消息隊列。把它看成是你在閱讀無限文件。

所以,如果你想讀的字符串出文件,你需要一些方法來將它們分開。它可以是一個分隔符,或者你可以在字符串的長度前加字母,或者其他什麼。

+0

但我沒有問題的服務器:當它需要'\ n'刷新流。客戶端,否則,只是打印'\ n'。我真的不知道你的意思是通過實施我自己的協議。如果一個操作碼給每種類型的消息,我怎麼能在它之前檢測到消息繼續閱讀?你有什麼資料可以查詢嗎?謝謝。 – synack 2012-04-25 17:39:07

+0

@ user1336939編輯。 – 2012-04-26 08:18:58