Всем привет!
Пытаюсь "поднять сервер" на фф через nsIServerSocket. Исключительно в образовательных целях.
Но столкнулся с проблемой. Не получается нормально считать данные из openInputStream(0,0,0).
Точнее данные то приходят, то не приходят. Попытался реализовать чтение данных двумя способами server_01, server_02
Так server_01, иногда считывает данные, иногда нет.
В server_02 попытался решить проблему через nsIInputStreamPump и onDataAvailable, считать данные не получаица, хотя атрибут count передаваемый onDataAvailable видит число переданных данных.

Делаю под Xulrunner (ver. 1.9.2.3506) / ОС WinXP

//----------------------------------------------------//
Client:

Выделить код

Код:

function client(host,port,outputData)
{
    alert(host+port+outputData);
    var tr_service = Components.classes["@mozilla.org/network/socket-transport-service;1"].getService(Components.interfaces.nsISocketTransportService);
    var tr = tr_service.createTransport(null,0,host,port,null);
    
    var i_put_tr = tr.openInputStream(0,0,0);
    var o_put_tr = tr.openOutputStream(0,0,0);
        
        o_put_tr.write(outputData,outputData.length);
        
    //var stream = transport.openInputStream(0,0,0);
    var i_put_sis = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance(Components.interfaces.nsIScriptableInputStream);
        i_put_sis.init(i_put_tr);

    var dataListener =
    {
        onStartRequest: function(request, context){},
        onStopRequest: function(request, context, status)
        {
            instream.close();
            outstream.close();
        },
        onDataAvailable: function(request, context, inputStream, offset, count){
            alert(i_put_sis.read(count));
        },
    };
    var pump = Components.classes["@mozilla.org/network/input-stream-pump;1"].createInstance(Components.interfaces.nsIInputStreamPump);
    pump.init(i_put_tr, -1, -1, 0, 0, false);
    pump.asyncRead(dataListener,null);
}

client("127.0.0.1",7055,"123");

//----------------------------------------------------//
Server_01:

Выделить код

Код:

var sS;
function server_01()
{
   var listener =
   {
      onSocketAccepted : function(socket, transport)
      {
         var i_put_tr = transport.openInputStream(0,0,0);
         var o_put_tr = transport.openOutputStream(0,0,0);
         
         var bin_stream = Components.classes["@mozilla.org/binaryinputstream;1"].createInstance(Components.interfaces.nsIBinaryInputStream);
         bin_stream.setInputStream(i_put_tr);
         
         var data = bin_stream.readByteArray(bin_stream.available());
         
         var output_message = "Server message, data: "+data;
         o_put_tr.write(output_message,output_message.length);
         o_put_tr.close();
      },
      onStopListening : function(socket, status){}
   };
   sS = Components.classes["@mozilla.org/network/server-socket;1"].createInstance(Components.interfaces.nsIServerSocket);
   sS.init(7055,true,0);
   sS.asyncListen(listener);
}
server_01();

//----------------------------------------------------//
Server_02:

Выделить код

Код:

var sS;
function server_02()
{
   sS_Listener =
   {
      onSocketAccepted : function(socket, transport)
      {
         server_get_data(socket, transport);
      },
      onStopListening : function(socket, status)
      {
         //...
      }
   };
   sS = Components.classes["@mozilla.org/network/server-socket;1"].createInstance(Components.interfaces.nsIServerSocket);
   sS.init(7055,true,0);
   sS.asyncListen(sS_Listener);
}

function server_get_data(socket, transport)
{
   var i_put_tr = transport.openInputStream(0,0,0);//.QueryInterface(Components.interfaces.nsIAsyncInputStream);
   var o_put_tr = transport.openOutputStream(0,0,0);
   
   var dataListener =
   {
      onStartRequest: function(request, context)
      {
         document.getElementById('log').value="";
      },
      onStopRequest: function(request, context, status){},
      onDataAvailable: function(request, context, inputStream, offset, count){
         document.getElementById('log').value="Data available.\n Count:"+count; // Выдает длинну переданных данных, т.е. както данные читает
         alert(i_put_bin.available()); // Всегда выдает 0, не видит данных
      },
   };

   var i_put_bin = Components.classes["@mozilla.org/binaryinputstream;1"].createInstance(Components.interfaces.nsIBinaryInputStream);
   i_put_bin.setInputStream(i_put_tr);
   
   var pump = Components.classes["@mozilla.org/network/input-stream-pump;1"].createInstance(Components.interfaces.nsIInputStreamPump);
   pump.init(i_put_bin, -1, -1, 0, 0, false);
   pump.asyncRead(dataListener,null);
}
server_02();

zibloid
Может быть, потому, что после выполнения client() переменной dataListener уже не существует ?

Чтоб считать данные присланные серверу, именно когда они пришли, использовал атрибут inputStream в onDataAvailable (см. Server_02)

Выделить код

Код:

onDataAvailable: function(request, context, inputStream, offset, count)
{         
     var read_is = inputStream.QueryInterface(Components.interfaces.nsIInputStream);
     var read_sis = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance(Components.interfaces.nsIScriptableInputStream);
     read_sis.init(read_is);
     
     alert(read_sis.read(count)); //Выведет переданные от клиента данные

}

Не знаю на сколько это правильно, но это работает. Теперь сервер считывает данные только когда они пришли.
Но! Клиенту приходится многократно посылать серверу сообщения, до тех пор пока сервер не пришлет ему какиенить данные обратно. При этом сервак "видит" все подключения клиента.
Попробывал отсылать серверу сообщения с помощью nsIAsyncOutputStream, но это не сильно помогает, сиравно приходится отсылать много сообщений.

Ща ковыряю POW  и httpd.js, посморим мож ченить найду.

13-09-2009 05:37:53

Anton пишет

zibloid
Может быть, потому, что после выполнения client() переменной dataListener уже не существует ?

Впринципе после выполнения client() обьект dataListener и не нужен, все операции над прислаными данными можно запихать в dataListener.onDataAvailable.

Все, разобрался! :) Помог код POW. Теперь ФФ слушает заданый порт, читает сообщения от клиента и отсылает клиенту отвтеные сообщения :) Класс, ФФ красатуля!

Вот готовое решение:

Выделить код

Код:

var sS;
function server_02()
{
   sS_Listener =
   {
      onSocketAccepted : function(socket, transport)
      {
         server_get_data(socket, transport);
      },
      onStopListening : function(socket, status)
      {
         //...
      }
   };
   sS = Components.classes["@mozilla.org/network/server-socket;1"].createInstance(Components.interfaces.nsIServerSocket);
   sS.init(7055,false,-1);
   sS.asyncListen(sS_Listener);
}

function server_get_data(socket, transport)
{
   var i_put_tr = transport.openInputStream(0,0,0);
   var o_put_tr = transport.openOutputStream(0,0,0);

   var i_put_bin = Components.classes["@mozilla.org/binaryinputstream;1"].createInstance(Components.interfaces.nsIBinaryInputStream);
   i_put_bin.setInputStream(i_put_tr);
   transport.setTimeout(1, 5);

   var dataListener =
   {
      onStartRequest: function(request, context)
      {
           //...
      },
      onStopRequest: function(request, context, status){},
      onDataAvailable: function(request, context, inputStream, offset, count)
      {
         var b_in = Components.classes["@mozilla.org/binaryinputstream;1"].createInstance(Components.interfaces.nsIBinaryInputStream);
         b_in.setInputStream(i_put_tr);      
         var str="You send: "+"\n"+decodeURIComponent(b_in.readBytes(count));
         o_put_tr.write(str,str.length);
         i_put_tr.close();
         o_put_tr.close();
      },
   };
   
   var pump = Components.classes["@mozilla.org/network/input-stream-pump;1"].createInstance(Components.interfaces.nsIInputStreamPump);
   pump.init(i_put_tr, -1, -1, 0, 0, true);
   pump.asyncRead(dataListener,null);
}

server_02();