如何在我的代码中刷新套接字 [英] How to flush a socket in my code

查看:77
本文介绍了如何在我的代码中刷新套接字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在通过套接字从FF附加组件写入Java服务器.我写了几个请求,服务器似乎一对一处理它们.相反,来自服务器的响应全部同时处理.

我尝试刷新服务器中的输出流,但是它什么也没做.我不明白发生了什么事.

感谢您的帮助,谢谢.

可能是附加组件(客户端)没有刷新输入流,这可能吗?我在Java服务器中使用out.println,因此'\ n'必须刷新其输出流,并且网络库使用write.flush(),但看不到其他刷新输入.

这是我的代码:

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

解决方案

您正在同步写入输出流,这意味着在执行此操作时无法运行其他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);
}

您将在pump.asyncRead()之后以及onDataAvailable中的代码中调用sendNextString(outstream).

PS:据我所知,刷新流不是这里的问题-您正在使用非缓冲流.

I'm writing through a socket from a FF add-on to a java server. I write several requests and the server seems to process them one-by-one. In contrast, the responses from the server are processed all at the same time.

I've tried flushing the out stream in the server but it does nothing. I don't understand what's going on.

I appreciate any help, thank you.

EDIT1: May be the add-on (client) is not flushing the input stream, is that possible? I'm using in the java server the out.println so the '\n' must flusht its output stream and the net library uses the write.flush(), but I don't see any other flush for the input.

EDIT2: Here is my code:

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;
};

So, when I run it, I get:

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

And it should be:

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

解决方案

You are writing to the output stream synchronously, that means that no other JavaScript code can run while you do it. So receiving anything from the server while you are writing is impossible, incoming data is simply put into a buffer.

The other issue is that you are sending the next string without waiting for the response from server. Normally, you will be able to send off both of them before the server response arrives. You probably want to send the next string only when you receive the response to the previous one.

You probably want to use a send function like this one:

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);
}

And you would call sendNextString(outstream) in your code after pump.asyncRead() as well as in onDataAvailable.

PS: From what I can tell, flushing the stream is not the issue here - you are using a non-buffering stream.

这篇关于如何在我的代码中刷新套接字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆