forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   JavaScript / HTML (http://forum.boolean.name/forumdisplay.php?f=136)
-   -   Node JS net модуль (http://forum.boolean.name/showthread.php?t=18700)

pax 11.11.2013 13:10

Node JS net модуль
 
В общем проблема с регистрацией отключений от сервера. Может и в коде есть какие-то косяки... надо искать. Сейчас самое главное понять как правильно ловить отключение сокета.

В общем вопрос такой: Какой эвент приходит всегда при отключении?

Такое ощущение, что евент 'close' срабатывает не во всех случаях... 'end' срабатывает всегда?

moka 12.11.2013 01:13

Ответ: Node JS net модуль
 
На сервере, клиентский сокет выдаст 'end' только в случае при получении пакета FIN от клиента. Это естественно не всегда будет так.
Иногда нужно слушать 'error' тоже, хотя документация говорит о 'close' всегда после него.
'close' выдаст только когда сокет полностью закрыли.

Какую версию node.js используешь? (node --version) или process.version
Возможно сокет хандлиться по какой-то причине.

Проверь если end + error + close хоть один но будет всегда триггериться, то нужно проверить где стопорится.

Также есть ещё setTimeout если ты будешь уверен что сервер будет периодически пинговать клиента, то ставь таймаут.

pax 12.11.2013 07:09

Ответ: Node JS net модуль
 
Да уже поставил для теста дисконнект во все эвенты, в таймаут тоже. Тестируем. Версию нода у ant2on'а спрошу. Я разрабатываю на последней версии. Про пинг думал, но это как бы костыль имхо. Но в будущем его заюзаю.

Phantom 12.11.2013 11:38

Ответ: Node JS net модуль
 
Экспериментировал как-то с WebSocket, написал простой код, вроде бы без ошибок и решил его нагнуть путём соединения, отправки пакета, отсоединения с нескольких клиентов в цикле почти без задержки. В итоге периодически на сервере выскакивало исключение, уже точно не помню какое. В принципе если его гасить обработчиком всех неперехваченных исключений, всё работает как надо и утечек вроде нет, но как избавиться от него, я так и не понял. Гугл тоже не помог. Сервер запускал на Windows 7, возможно проблема специфична для винды.

pax 12.11.2013 13:30

Ответ: Node JS net модуль
 
Ну вэбсокеты меня не интересуют. Проверили снова. Все еще не всех дисконнектит...

moka 13.11.2013 00:48

Ответ: Node JS net модуль
 
pax код в студию.
И способ воспроизведения.

Phantom, когда говоришь о конкретном модуле - референс давай на него, в socket.io там есть heartbeat и нужно учитывать - это не баг а фича.
А вот в 'ws' не трогал, но там постоянно фиксы выходят.

В 95% подобных багах я в итоге находил причины которые были на моей стороне от части - недопонимание каких-то настроек и т.п.
Бывают проблемы на стороне модуля - но нужно всегда ловить и делать конкретный пример воспроизведения, и не лениться создавать issue на гите, я так в mongodb например баг серьёзный описал - пофиксили через неделю!

pax 13.11.2013 01:21

Ответ: Node JS net модуль
 
Цитата:

Сообщение от moka (Сообщение 270122)
pax код в студию.
И способ воспроизведения.

Кода сейчас достаточно много, чтобы его сюда выкладывать и надо клиент на Unity тоже.

Регулярная отсылка пинг-пакета успешно отсоединяет клиентов.

Исправил баг неверной передачи размера пакета, сервер в этом случае пытался ждать большого объема данных, но почему не дисконнектил при дисконнекте клиента все еще не понятно. Тестируем дальше.

pax 13.11.2013 14:17

Ответ: Node JS net модуль
 
Написал сервер-сервер сеть
PHP код:

var util = require('util');
var 
NodeSharpTCP = require('NodeSharpTCP');

// евент сервер
var EventServer NodeSharpTCP.EventServer;

var 
server = new EventServer();
server.setSendRate(10);

server.on('connection', function (client) {

    
console.log('Clients: ' server.clients.length);

    
client.on('disconnect', function () {
        
console.log('Clients: ' server.clients.length);
    });

    
client.on('World', function (data) {
        
console.log('World: ' util.inspect(data));
        
client.emit('Hello'data 1);
    });

    
client.emit('Hello'1);
});


server.listen(8124, function () {
    
console.log('Event Server bound')
});


// клиент евент сервера
var EventServerClient NodeSharpTCP.EventServerClient;

var 
client = new EventServerClient();
client.setSendRate(10);

client.on('Hello', function (data) {
    
console.log('Hello: ' util.inspect(data));
    
client.emit('World'data 1);
});

client.connect(8124'localhost', function () {
    
console.log('client connected');
}); 

Результат работы
Код:

C:\nodejs\node.exe eventServerClientTest.js
Event Server bound
client connected
Clients: 1
Hello: 1
World: 2
Hello: 3
World: 4
Hello: 5
World: 6
Hello: 7
World: 8
Hello: 9
World: 10
Hello: 11
...


moka 14.11.2013 00:46

Ответ: Node JS net модуль
 
Думаю не нужно использовать Event в node.js, т.к. это и так подрузумевается и обыденное дело.

А так збсь, только вопрос: что за магическое число 10 setSendRate?
Есть на гите?

pax 14.11.2013 07:27

Ответ: Node JS net модуль
 
Цитата:

Сообщение от moka (Сообщение 270189)
Думаю не нужно использовать Event в node.js, т.к. это и так подрузумевается и обыденное дело.

Не понял на счет Event, не использовать приставку к объектам? У меня там есть отдельно TCPSetrver и TCPServerClient, т.к. евент сервер и клиент это обертки над ними.

Цитата:

Сообщение от moka (Сообщение 270189)
А так збсь, только вопрос: что за магическое число 10 setSendRate?

Это частота отправки. 10 раз в секунду. Если приходит много пакетов, то при отправке они клеятся в один буфер.

Кстати по этому поводу есть вопрос по архитектуре. Сейчас у меня общий цикл, который берет всех клиентов которым пришли пакеты и по очереди отправляет, т.е. я собираю в массив всех кому пришли пакеты. При отправке я создаю новый пустой массив, а текущий перебираю. Это норм, или каждому клиенту сделать свой цикл с setTimeout?

Цитата:

Сообщение от moka (Сообщение 270189)
Есть на гите?

Сейчас оно на моем сервере на svn, по поводу публичного доступа я пока еще не думал.

moka 15.11.2013 04:33

Ответ: Node JS net модуль
 
Цитата:

Сообщение от pax (Сообщение 270202)
Не понял на счет Event, не использовать приставку к объектам? У меня там есть отдельно TCPSetrver и TCPServerClient, т.к. евент сервер и клиент это обертки над ними.

Ну ты всё ещё в синхронном мире ;) Обычно если такие вещи делают то естественно только асинхронно, т.к. это же IO.


Цитата:

Сообщение от pax (Сообщение 270202)
Это частота отправки. 10 раз в секунду. Если приходит много пакетов, то при отправке они клеятся в один буфер.

Уф.
Ну тут важно одно - соблюдать очередь вызовов отправки, остальное не важно.
У тебя есть stream'ы, засунуть в них данные на отправку времени много не занимает (смотря как сериализаия сделана).
Поэтому не думаю что стоит тут пытаться переоптимизировать (клеить пакеты и т.п.).
Пользователь вызвал - вот и шли сразу, не стоит делать таймауты и задержки, т.к. это лишние телодвижения.
Тем более если мы хотим что-то подобное:
PHP код:

socket.emit('foo');
socket.disconnect(); 

Цитата:

Сообщение от pax (Сообщение 270202)
Кстати по этому поводу есть вопрос по архитектуре. Сейчас у меня общий цикл, который берет всех клиентов которым пришли пакеты и по очереди отправляет, т.е. я собираю в массив всех кому пришли пакеты. При отправке я создаю новый пустой массив, а текущий перебираю. Это норм, или каждому клиенту сделать свой цикл с setTimeout?

Не нужно никаких циклов и итераций. Кодер хочет слать сообщение - вот и шли сообщение. Шлёт слишком много? - проблема кодера. Если он сам не заботиться о нормальных пакетах и т.п. Тем более в играх редко используют event-основанную систему, а чаще всего шлют пакеты со state'ами а они большие.
Так что юзер сам об этом должен заботиться, и не пытайся решать за него какие-то задачи, тем более если это вносит задержку в 10мс.
Т.к. делая это в node.js - это не сэкономит на производительности, процессору всё равно это нужно сделать и если это делает node то это выполняется в том же потоке - следственно от перестановки мест - скорость не поменяется, а вот задержку этим ты создашь.

Если тебя заботит скорость сериализации - то тут нужно брать C++ и писать именно эту часть как Addon (module), в нете полно доков и будет очень подобно C# в плане работы с данными.

В разработке node модулей очень важно соблюдать их простоту и конкретность в том что они делают. А юзер уже сам там решит что и как с этим делать (нужно клеить пакеты или не нужно и т.п.).
Т.к. ты по сути сделал NoDelay (Nagle's Algorithm).

Цитата:

Сообщение от pax (Сообщение 270202)
Сейчас оно на моем сервере на svn, по поводу публичного доступа я пока еще не думал.

Можно заюзать bitbucket в котором есть приватные бесплатные репозитории.
Я бы хотел изучить то как работает модуль и что он пытается сделать, и разработать архитектуру которая будет удобна в использовании и достаточно гибка для возможных изменений, и обсудили бы это далее..

pax 15.11.2013 07:21

Ответ: Node JS net модуль
 
Цитата:

Сообщение от moka (Сообщение 270262)
Ну тут важно одно - соблюдать очередь вызовов отправки, остальное не важно.

Ты сам говорил когда-то, что твой сервер при реалтайме загибался когда в комнате 20 игроков и каждый шлет 30 раз в секунду сообщения по 10 байт к примеру. С учетом TCP заголовка это еще + 40..60 байт.

Функционал склейки сообщений отключается если не нужен.

Цитата:

Сообщение от moka (Сообщение 270262)
Тем более если мы хотим что-то подобное:
PHP код:

socket.emit('foo');
socket.disconnect(); 


Вот про это спасибо, вероятно у меня это не прокатит если используется склейка пакетов).

Цитата:

Сообщение от moka (Сообщение 270262)
Можно заюзать bitbucket в котором есть приватные бесплатные репозитории.
Я бы хотел изучить то как работает модуль и что он пытается сделать, и разработать архитектуру которая будет удобна в использовании и достаточно гибка для возможных изменений, и обсудили бы это далее..

Могу дать доступ к svn.

moka 16.11.2013 05:27

Ответ: Node JS net модуль
 
Цитата:

Сообщение от pax (Сообщение 270267)
Ты сам говорил когда-то, что твой сервер при реалтайме загибался когда в комнате 20 игроков и каждый шлет 30 раз в секунду сообщения по 10 байт к примеру. С учетом TCP заголовка это еще + 40..60 байт.

У меня ложилось потому что у меня руки кривые :-D
30 раз в секунду по 40-60 байт это 36000 байт в секунду на пользователя, весьма не оптимизированный объём данных и т.п. имхо, и 30 раз в секунду - слишком часто для большинства, тем более ММО игр.
Да и это скорее проблемы разраба а не твои ;)

Цитата:

Сообщение от pax (Сообщение 270267)
Функционал склейки сообщений отключается если не нужен.

Если он опциональная фича по стандарту (выключен), то это вполне нормально.

Цитата:

Сообщение от pax (Сообщение 270267)
Могу дать доступ к svn.

На этих выходных 48 часовой hackathon, так что буду кодить все выходны, и на работе сегодня был тоже hackathon весь день :) так что гляну на следующей недели. :)


Часовой пояс GMT +4, время: 14:39.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot