2015-04-05 5 views
0

Я пишу сервер игры TCP в Node.js, и у меня возникают проблемы с разделением потока TCP на сообщения. Поскольку я хочу читать числа и поплавки из буфера, я не могу найти подходящий модуль для аутсорсинга, поскольку все те, которые я нашел, имеют дело с простыми строками, заканчивающимися новым разделителем строк. Я решил перейти с префиксом каждого сообщения длиной в байтах сообщения. Я сделал это и написал простую программу для спама сервера со случайными сообщениями (хорошо построенными с префиксом UInt16LE, изображающим длину сообщения). Я заметил, что чем дольше я оставляю программы, работающие на моем реальном сервере, тем больше использует память. Я попытался использовать инструмент отладки, чтобы трассировать выделение памяти без успеха, поэтому я решил, что разместил здесь свой код и надеюсь на ответ. Итак, вот мой код ... любые советы или указатели относительно того, где я иду не так, или что я могу сделать по-другому/более эффективно, было бы потрясающе! Спасибо.Ошибка утечки памяти Node.js net tcp

server.on("connection", function(socket) { 
var session = new sessionCS(socket); 
console.log("Connection from " + session.address); 

// data buffering variables 
var currentBuffer = new Buffer(args.bufSize); 
var bufWrite = 0; 
var bufRead = 0; 
var mSize = null; 
var i = 0; 

socket.on("data", function(dataBuffer) { 

    // check if buffer risk of overflow 
    if (bufWrite + dataBuffer.length > args.bufSize-1) { 
     var newBufWrite = 0; 
     var newBuffer = new Buffer(args.bufSize); 

     while(bufRead < bufWrite) { 
      newBuffer[newBufWrite] = currentBuffer[bufRead]; 
      newBufWrite++; 
      bufRead++; 
     } 

     currentBuffer = newBuffer; 
     bufWrite = newBufWrite; 
     bufRead = 0; 
     newBufWrite = null; 
    } 

    // appending buffer 
    for (i=0; i<dataBuffer.length; i++) { 
     currentBuffer[bufWrite] = dataBuffer[i]; 
     bufWrite ++; 
    } 

    // if beginning of message not acknowleged 
    if (mSize === null && (bufWrite - bufRead) >= 2) { 
     mSize = currentBuffer.readUInt16LE(bufRead); 
    } 

    // if difference between read and write is greater or equal to message mSize + 2 
    // +2 for the integer holding the message size 
    // this means that a full message is in the buffer and needs to be extracted 
    while ((bufWrite - bufRead) >= mSize+2) { 
     bufRead += 2; 
     var messageBuffer = new Buffer(mSize); 

     for(i=0; i<messageBuffer.length; i++) { 
      messageBuffer[i] = currentBuffer[bufRead]; 
      bufRead++; 
     } 

     // this is where the message buffer would be passed to the router 
     router(session, messageBuffer); 
     messageBuffer = null; 

     // seeinf if another message length indicator is in the buffer 
     if ((bufWrite - bufRead) >= 2) { 
      mSize = currentBuffer.readUInt16LE(bufRead); 
     } 
     else { 
      mSize = null; 
     } 
    } 
}); 
} 
+0

Что вы используете для измерения использования памяти сервера? Это может быть сложной задачей для правильного измерения, если не сделано правильно, и вы можете легко ввести в заблуждение системным кэшированием и поисковым вызовом. – jfriend00

+0

@ jfriend00 im работает над моими окнами 7, так что просто старый менеджер задач. im положительный есть утечка, потому что, если я оставлю клиента спам сервера в течение примерно 10-15 минут, сервер будет использовать более 1 гигабайта памяти! и его начальное состояние до того, как клиент начнет спам, составляет около 50 кб .. вы можете очень четко видеть его повышение –

+0

Что делает функция 'router()'? Вы очищаете ссылку на сеанс при отключении? – jfriend00

ответ

0

Буфер кадра Сериализация Protocol (BUFSP) https://github.com/teambition/bufsp Это может быть, что вы хотите: кодировать сообщения в буфер, писать TCP, получать и разделив TCP потока буфера в сообщения.

+0

Позволяет ли оно одновременно отправлять сообщения (например, отправлять сообщения одновременно с отправкой большого файла)? – blablabla

Смежные вопросы