2011-08-12 12 views
5

Z tego, co zrozumiałem, here, "V8 ma pokoleniowy garbage collector, losowo przesuwa obiekty.Node nie może uzyskać wskaźnika do nieprzetworzonych danych ciągu do zapisu do gniazda." więc nie powinienem przechowywać danych pochodzących ze strumienia TCP w ciągu znaków, szczególnie jeśli ten ciąg staje się większy niż Math.pow(2,16) bajtów. (mam nadzieję, że mam rację do tej pory ...)NodeJS: Jaki jest właściwy sposób obsługi strumieni gniazd TCP? Którego ogranicznika powinienem użyć?

Jaki jest zatem najlepszy sposób na obsłużenie wszystkich danych pochodzących z gniazda TCP? Do tej pory próbowałem użyć _:_:_ jako ogranicznika, ponieważ uważam, że jest on w jakiś sposób wyjątkowy i nie zawadzi o inne rzeczy.

Próbkę danych, które przyjdzie byłoby something_:_:_maybe a large text_:_:_ maybe tons of lines_:_:_more and more data

To co próbowałem zrobić:

net = require('net'); 
var server = net.createServer(function (socket) { 
    socket.on('connect',function() { 
     console.log('someone connected'); 
     buf = new Buffer(Math.pow(2,16)); //new buffer with size 2^16 
     socket.on('data',function(data) { 
      if (data.toString().search('_:_:_') === -1) { // If there's no separator in the data that just arrived... 
       buf.write(data.toString()); // ... write it on the buffer. it's part of another message that will come. 
      } else {  // if there is a separator in the data that arrived 
       parts = data.toString().split('_:_:_'); // the first part is the end of a previous message, the last part is the start of a message to be completed in the future. Parts between separators are independent messages 
       if (parts.length == 2) { 
        msg = buf.toString('utf-8',0,4) + parts[0]; 
        console.log('MSG: '+ msg); 
        buf = (new Buffer(Math.pow(2,16))).write(parts[1]); 
       } else { 
        msg = buf.toString() + parts[0]; 
        for (var i = 1; i <= parts.length -1; i++) { 
         if (i !== parts.length-1) { 
          msg = parts[i]; 
          console.log('MSG: '+msg); 
         } else { 
          buf.write(parts[i]); 
         } 
        } 
       } 
      } 
     }); 
    }); 
}); 

server.listen(9999); 

Ilekroć próbuję console.log('MSG' + msg) będzie wydrukować cały bufor, dlatego bezużyteczne, aby sprawdzić, czy coś działa.

Jak mogę obsłużyć te dane we właściwy sposób? Czy moduł leniwy działałby, nawet jeśli dane te nie są zorientowane liniowo? Czy jest jakiś inny moduł do obsługi strumieni, które nie są zorientowane liniowo?

+1

Prezentacja do którego połączony jest mówić o pisanie * * Informacje na gniazdach. Czytasz to, więc obawy są różne. W pliku node.js 0.4.6 wywołanie danych daje już bufor do pracy, chyba że zostanie określone kodowanie, w którym to przypadku otrzymasz ciąg znaków. Sposób utrzymywania danych po tym zależy od tego, jaki jest Twój aktualny cel. –

+0

Czy to oznacza, że ​​mogę przechowywać przychodzące bufory jako duży ciąg i czy nie występują problemy z wydajnością? –

Odpowiedz

4

Rzeczywiście powiedziano, że trwają dodatkowe prace, ponieważ węzeł musi wziąć ten bufor, a następnie wcisnąć go w v8/rzucić na łańcuch. Jednak wykonanie funkcji toString() na buforze nie jest lepsze. Nie ma na to dobrego rozwiązania, o ile mi wiadomo, zwłaszcza jeśli twoim celem jest zdobycie sznurka i wygłupienie się z nim. Jest to jedna z rzeczy, o której Ryan wspomniał @ nodeconf jako obszar, w którym należy wykonać pracę.

Co do ogranicznika, możesz wybrać, co chcesz. Wiele protokołów binarnych decyduje się na dołączenie stałego nagłówka, dzięki czemu można umieścić rzeczy w normalnej strukturze, która wiele razy zawiera długość. W ten sposób dzielisz znany nagłówek i otrzymujesz informacje o pozostałych danych bez konieczności powtarzania całego bufora. W systemie takim, można zastosować narzędzie, takie jak:

Nawiasem bufory można uzyskać poprzez składni tablicy, i mogą być również rozcinane na kawałki przy pomocy .slice().

Na koniec sprawdź tutaj: https://github.com/joyent/node/wiki/modules - znajdź moduł, który analizuje prosty protokół TCP i wygląda na to, że robi to dobrze, i przeczytaj trochę kodu.

Powiązane problemy