NodeJS: Как правильно обрабатывать потоки сокетов TCP? Какой разделитель я должен использовать? - PullRequest
6 голосов
/ 12 августа 2011

Из того, что я понял здесь , "V8 имеет сборочный сборщик мусора. Случайно перемещает объекты. Узел не может получить указатель на необработанные строковые данные для записи в сокет".поэтому я не должен хранить данные, поступающие из потока TCP, в строку, особенно если эта строка становится больше, чем Math.pow(2,16) байтов.(надеюсь, я прав до сих пор ..)

Каков наилучший способ обработки всех данных, поступающих из сокета TCP?До сих пор я пытался использовать _:_:_ в качестве разделителя, потому что я думаю, что он как-то уникален и не будет мешать другим вещам.

Примером данных, которые будут получены, будет something_:_:_maybe a large text_:_:_ maybe tons of lines_:_:_more and more data

Вот что я пытался сделать:

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

Всякий раз, когда я пытаюсь console.log('MSG' + msg), он распечатывает весь буфер, поэтому бесполезно видеть, работает ли что-то.

Как мне правильно обрабатывать эти данные?Будет ли работать ленивый модуль, даже если эти данные не ориентированы на строки?Есть ли какой-то другой модуль для обработки потоков, которые не ориентированы на строки?

Ответы [ 2 ]

6 голосов
/ 13 августа 2011

Действительно, было сказано, что идет дополнительная работа, потому что Node должен взять этот буфер и затем поместить его в v8 / привести его к строке. Однако выполнение toString () в буфере не лучше. Насколько я знаю, сейчас нет хорошего решения этого вопроса, особенно если ваша конечная цель состоит в том, чтобы наброситься на нее и пошутить. Это одна из вещей, которые Райан упомянул @ nodeconf как область, где необходимо выполнить работу.

Что касается разделителя, вы можете выбрать все, что захотите. Многие бинарные протоколы предпочитают включать фиксированный заголовок, так что вы можете поместить вещи в нормальную структуру, которая часто включает длину. Таким образом, вы разделяете известный заголовок и получаете информацию об остальных данных без необходимости перебирать весь буфер. С такой схемой можно использовать такой инструмент:

Кроме того, к буферам можно получить доступ через синтаксис массива, а также их можно разделить на части с помощью .slice ().

Наконец, проверьте здесь: https://github.com/joyent/node/wiki/modules - найдите модуль, который анализирует простой протокол tcp и, кажется, делает это хорошо, и прочитайте некоторый код.

3 голосов
/ 12 июля 2013

Вы должны использовать новый API stream2.http://nodejs.org/api/stream.html

Вот несколько очень полезных примеров: https://github.com/substack/stream-handbook

https://github.com/lvgithub/stick

...