PDA

Просмотр полной версии : WebSocket vs Socket


faraday
01.12.2015, 21:57
Всегда использовал стандартный сокет для обмена данными с сервером, и так же всегда интересовал вопрос куда стабильно пропадают 3-5 процентов подключений. Проверялось так: одновременно с подключением к сокету отправлялся http запрос. В итоге около 5 процентов соединений в час числилось пропавшими без вести. Первое что приходит в голову что подключения блокирует фаервол, поэтому решил попробовать подключаться на 80 порт, через webSocket(worlize), в итоге потерянных соединений стало на пару процентов больше. Отсюда вопросы:
Какие дает преимущества использование websocket? почему если он работает через http, его так же не пропускают фаерволы? или через http только рукопожатие, а потом передача обычным сокетом.
Какие еще могут быть причины что http(не 80-й порт) проходит, а сокет нет?
Стоит ли пробовать socket.io? сомневаюсь что он тут чем то поможет
Стоит ли при неудаче подключения на сокет, открывать лонгполинг http?
Или вообще 5 процентов - это нормально и переживать не стоит?

caseyryan
02.12.2015, 06:35
В итоге около 5 процентов соединений в час числилось пропавшими без вести
Первое что приходит в голову что подключения блокирует фаервол
Это что, такой избирательный фаервол?) Мол, дай-ка я этот пакет пропущу, а этот на таможне придержу :D
Фаерволл либо блокирует все подключения от программы, либо никаких. Зачем ему блокировать 5% отдельных пакетов? Это же не антивирус, который все пакеты проверяет и опасные блокирует.
Стоит ли при неудаче подключения на сокет, открывать лонгполинг http?
Думаю да. Такая штука есть во многих готовых серверах. Называется http failover

faraday
21.01.2016, 17:29
Это что, такой избирательный фаервол?) Мол, дай-ка я этот пакет пропущу, а этот на таможне придержу
Фаерволл либо блокирует все подключения от программы, либо никаких. Зачем ему блокировать 5% отдельных пакетов? Это же не антивирус, который все пакеты проверяет и опасные блокирует.

Тем не менее проблема остается и раз за разом воспроизводится.
сервер:
function socketHandler(socket){
socket.setEncoding('utf8');
socket.setTimeout(300000);
socket.setNoDelay(true);
socketMsgHandler(socket);
// socket.write(getCrossDomainFile() + '\0');
}

function socketMsgHandler(socket){
carrier.carry(socket, function(msg){
if (msg=='<policy-file-request/>'){
socket.write(getCrossDomainFile()+'\0');
socket.destroy();
}
},'utf8', '\0');
}
клиент:
newSocket = new XMLSocket();
newSocket.connect(host, port);
Security.loadPolicyFile("xmlsocket://"+host+":"+port);
newSocket.addEventListener(Event.CONNECT, newConnect);
newSocket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, secError);
на 8112 порту http сервер
на 8113 порту сокеты
при загрузке отсылаю на http tryConnect, так же, для проверки соединения, спустя 5 сек отсылаю checkConnection.
+ на http логирую результат сокет соединения security, ioError, success.
в итоге на 1000 подключений tryConnect=1000, checkConnection=999, success: 955, security:10. Не понятно откуда взялись эти 10, и куда пропали 34 соединения. при этом до http сервера все достукиваются без проблем.

Tails
21.01.2016, 18:04
Сперва необходимо подписаться на все нужные события и уже потом вызывать .connect(). Мало ли?

Когда клиент запрашивает политики, он всегда шлёт определённую строку по сокету, что-то вроде <police file request/>. Следует дождаться полного её получения, перед тем как слать файл политик.
После этого, на сервере соединение будет разорвано, вами или клиентом. И только потом, флеш клиент устанавливает рабочее соединение. Важно тут то, что для клиента это всё выглядит как одна попытка подключения, в то время как по факту происходит два подключения, первое для политик, второе рабочее.

faraday
21.01.2016, 18:51
в коде выше все эти моменты отражены. получает полностью <police file request/> (до нулевого байта), потом отвечает политикой и закрывает соединение. вот сам файл политик
function getCrossDomainFile()
{
var xml = '<?xml version="1.0"?>\n<!DOCTYPE cross-domain-policy SYSTEM'
xml += ' "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">';
xml += '\n<cross-domain-policy>\n';
xml += '<allow-access-from domain="*" to-ports="*"/>\n';
xml += '</cross-domain-policy>\n';
return xml;
}
Сперва необходимо подписаться на все нужные события и уже потом вызывать .connect(). Мало ли?
попробую, но врядли это что-то изменит, все хенделры асинхронные. к тому же можно установить подключение прямо из конструктора