Использование NetConnection и URLStream для отправки / получения данных с высокой частотой - PullRequest
1 голос
/ 18 июня 2009

Я пишу Comet-подобное приложение, используя Flex на клиенте и свой собственный рукописный сервер.

Мне нужно иметь возможность отправлять короткие пакеты данных от клиента с довольно высокой частотой (например, порядка 10 мс между отправками).

Мне также нужен сервер для передачи коротких пакетов данных с такой же высокой частотой.

Я использую NetConnection.call () для отправки данных на сервер и URLStream (с кусочной кодировкой) для передачи данных с сервера на клиент.

Я обнаружил, что данные не отправляются / не принимаются, как только они становятся доступными. Например, в IE кажется, что данные отправляются каждые 200 мс, а не как только вызывается NetConnection.call (). Аналогично, URLStream не делает данные доступными, как только сервер их отправляет.

Судя по разнице в поведении между браузерами, кажется, что Flash Player (версия 10) полагается на хост-браузер для выполнения всех сообщений. Кто-нибудь может это подтвердить? Обновление : Это очень вероятно, поскольку только браузер хоста может знать о настройках прокси, которые могут быть установлены.

Я пытался использовать класс Socket, и там нет проблем со скоростью: он отлично работает. Однако я хотел бы иметь возможность использовать HTTP-соединения (порт 80), чтобы мое приложение могло работать в средах с сильными огненными стенами (я пытался использовать Socket через порт 80, но у него есть свои проблемы).

Кстати, вся разработка / тестирование проводилась во внутренней локальной сети, поэтому пропускная способность / задержка не являются проблемой.

Обновление : отправляемые / получаемые данные находятся в небольших пакетах и ​​не должны быть в каком-либо конкретном формате. Например, мне может понадобиться отправить короткий массив Numbers, и это может быть либо закодировано в AMF (например, через NetConnection.call ()), либо может быть помещено в параметры GET (например, с помощью sendToURL ()). Суть моего вопроса в том, чтобы выяснить, действительно ли кто-то еще сталкивался с такой же проблемой при частом вызове NetConnection / URLStream, и есть ли обходной путь (возможно также, что ошибка связана с кодом моего сервера, а не с Flash) .

Спасибо.

Ответы [ 2 ]

1 голос
/ 21 июня 2009

Оказывается, проблема не имеет ничего общего с Flash / Flex или любым из браузеров хоста. Проблема была в моем серверном коде (написанном на C ++ в Linux), и без доступа к моему исходному коду причину трудно найти (поэтому я не мог надеяться на ответ с этого форума).

Тем не менее - спасибо всем, кто принял участие.

Только после тщательного изучения вывода, показанного в Wireshark , я заметил проблему, которая была двоякой:

Алгоритм Нэгла

Я отправлял ответы в нескольких пакетах, вызывая write () несколько раз (например, один раз для заголовка ответа HTTP и снова для тела ответа HTTP). Стек TCP / IP сервера ожидал ACK для первого пакета перед отправкой второго, но из-за алгоритма Nagle клиент ждал 200 мс, прежде чем отправить ACK на первый пакет, поэтому серверу потребовалось не менее 200 мс для отправки полный ответ HTTP.

Решение состоит в том, чтобы использовать send () с флагом MSG_MORE, пока не будут записаны все логически связанные блоки. Я мог бы также использовать writev () или setsockopt () с TCP_CORK, но мой существующий код лучше подходил для использования send () .

Потоково-кодированные потоки

Я использую бесконечный HTTP-ответ с кодировкой чанка для отправки данных обратно клиенту. Здесь необходимо отключить алгоритм Naggle, потому что даже если каждый блок записывается как один пакет (с использованием MSG_MORE), стек TCP / IP клиентской ОС все равно будет ждать до 200 мс, прежде чем отправлять ACK, и сервер не сможет выдвинуть последующий кусок, пока он не получит этот ACK.

Решение здесь состоит в том, чтобы попросить сервер не ждать ACK для каждого отправленного пакета перед отправкой следующего пакета, и это делается путем вызова setsockopt () с флагом TCP_NODELAY.

Вышеуказанные решения работают только в Linux и не POSIX-совместимы (я думаю), но для меня это не проблема.

0 голосов
/ 18 июня 2009

Я почти на 100% уверен, что для таких сообщений плеер использует браузер. Не могу найти официальную страницу с указанием так, но проверьте это , например:

Приложения, размещающие Flash Player Элемент управления ActiveX или Flash Player плагин может использовать EnforceLocalSecurity и API DisableLocalSecurity вызывает контролировать настройки безопасности.

Что, я думаю, как-то предполагает идею. Кроме того, я столкнулся с некоторыми сетевыми ошибками только в FF / IE, которые снова указывают на то, что проигрыватель использует каждый браузер для работы в сети (иначе таких различий не было бы).

А что касается вашей проблемы с задержкой, я думаю, что если скорость критична, ваша лучшая ставка - сокеты. У вас есть какая-то работа, но, кажется, это возможно, проверьте документы еще раз:

Эта ошибка возникает в содержимом SWF.
Отправляется, если вызов Socket.connect () пытается подключиться либо на сервер за пределами песочница безопасности звонящего или в порт ниже 1024. Вы можете обойти любая проблема с использованием междоменной файл политики на сервере.

НТН,

Juan

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...