Почему в этом случае Flash Player выдает ошибку «песочницы»? - PullRequest
19 голосов
/ 10 ноября 2009

Я получаю ошибку песочницы Flex 3 # 2048 после подключения к сокету на сервере Java (1.5). Код сервера полностью мой, то есть не работает под Apache. Flash Player 10.0 r32.

Последовательность следующая ...

1 Java-сервер запускается, прослушивает порт 843 для запроса файла политики и порт 45455 для других моих запросов.

2 Flex-клиент, обслуживаемый Apache (хотя я получаю тот же результат, если я запускаю его из файловой системы), подключение к сокету на хосте: 45455.

3 Flash Player запрашивает файл политики с порта 843. Это стандартное поведение, когда новые параметры безопасности ищут главный файл. Это происходит независимо от того, был ли указан другой файл политики.

4 Я передаю следующий XML из Java через порт 843:

<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<site-control permitted-cross-domain-policies="all"/>
<allow-access-from domain="*" to-ports="*" secure="false"/>
</cross-domain-policy>

5 Плеер записывает следующее в журнал политики отладки ...

OK: Root-level SWF loaded: http://localhost/bst/BasicSocketTest.swf
OK: Searching for <allow-access-from> in policy files to authorize data loading from resource at xmlsocket://192.168.2.3:45455 by requestor from http://localhost/bst/BasicSocketTest.swf
OK: Policy file accepted: xmlsocket://192.168.2.3:843
OK: Request for resource at xmlsocket://192.168.2.3:45455 by requestor from http://localhost/bst/BasicSocketTest.swf is permitted due to policy file at xmlsocket://192.168.2.3:843

6 Я отправляю текстовое сообщение от клиента на сервер через порт 45455, используя writeUTFBytes() и flush() (это мой собственный протокол сообщений, запеченный в домашних условиях, и правильно обрабатывается на каждом конце)

REG/REGISTER;simon;Si

7 Поток сервера Java, прослушивающий порт 45455, отвечает

REG:0/REGISTER:SUCCESS;simon;Si

8 Клиент Flex получает ProgressEvent и вызывается прослушиватель событий, который я привязал к сокету. Я обрабатываю сообщение (напишите его в текстовое поле на экране)

9 Проигрыватель Flash выдает ошибку «песочница» 2048, и розетка отключена! Это после сообщение получено и успешно обработано. На самом деле это около 12 секунд после. Больше ничего не работает через сокет.

Я попытался явно загрузить файл политики с помощью вызова Security.loadPolicyFile() в клиенте Flex, но реальность безопасности нового плеера заключается в том, что он в основном игнорируется. Шаги состоят в том, что запрос политики не будет отправлен, пока не произойдет операция ввода-вывода сокета. В этот момент проигрыватель всегда сначала переходит на порт 843 в поисках главного файла политики. Если он найдет его и он разрешит, он не пойдет дальше.

Я испробовал множество альтернативных способов завершения работы файла политики и содержимого файла политики, в том числе преднамеренные ошибки, просто чтобы проверить, проснулся ли Flash Player.

Я не вижу причин, по которым мне бросили бы 2048. Я точно подаю файл политики сокетов на указанном главном порте безопасности, который сам игрок регистрирует как правильный. Затем сокет успешно отправляет и получает сообщение с сервера, содержимое которого доступно для моего кода.

Кто-нибудь знает, почему это может происходить? Ошибка Flash Player?

PS Пожалуйста, не говорите мне использовать BlazeDS, LCDS или Granite, или что-то еще в качестве сервера, я ищу решение этой проблемы, а не перепроектировать. И, пожалуйста, не просите меня использовать вместо него XMLSocket - я попробовал это и получил точно такой же результат. Я тщательно и обдуманно выбрал свою архитектуру и хочу использовать бинарный сокет.

EDIT В ответ на запрос Джеймса Уорда в его комментарии, вот полное сообщение об ошибке:

Error #2048: Security sandbox violation: http://localhost/bst/BasicSocketTest.swf cannot load data from 192.168.2.3:45455.

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

RequestPolicy: 192.168.2.3:843
Create Socket: 192.168.2.3:45455
Connect: [Event type="connect" bubbles=false cancelable=false eventPhase=2]
Sending: REG/REGISTER;simon.palmer@gmail.com;Si
Receiving: REG:0/REGISTER:SUCCESS;simon.palmer@gmail.com;Si/
Close: [Event type="close" bubbles=false cancelable=false eventPhase=2]
Error #2048: Security sandbox violation: http://localhost/bst/BasicSocketTest.swf cannot load data from 192.168.2.3:45455.

Событие close вызывается сразу после успешного получения ответа от сервера, однако ошибка # 2048 появляется не раньше, чем через 20 секунд. Если я попытаюсь отправить еще одно сообщение после закрытия, но до ошибки, Flash Player выдаст недопустимое исключение сокета.

Я зарегистрировал ошибку в Adobe по этому поводу.

Я могу предоставить полный исходный код как клиента, так и сервера, если кому-то интересно.

Ответы [ 9 ]

3 голосов
/ 05 декабря 2009

Я проверял это локально, и, кажется, все работает нормально, пока сокет не закроется. Разве розетка не должна закрываться? После того как сообщение отправлено клиенту Flex, код Java выполняет следующие действия:

_in.close();
_out.close();
_socket.close();

Затем клиент Flex получает нарушение песочницы в следующий раз, когда он пытается связаться с сокетом. Если я снова создаю новое сокетное соединение, то отправка и получение работают нормально, а затем закрывается. Но через минуту или около того я получаю еще одно нарушение в песочнице. Интересно, пытается ли Flash пропинговать сокет, и поскольку он закрыт, он выдает нарушение режима песочницы?

2 голосов
/ 14 ноября 2009

Вы пытались добавить элемент allow-http-request-headers-from?

<allow-http-request-headers-from domain="*" headers="*" />

Или указать фактические порты вместо * для элемента allow-access-from?

<allow-access-from domain="*" to-ports="843,45455" />
1 голос
/ 01 декабря 2009

Это может или не может помочь вам, но у нас были похожие проблемы. Мы получали ошибку безопасности, но она была несовместимой. Я создал интерфейс и работал с разработчиком, который имел дело с Socket, написанным на PHP. Проблема, похоже, заключалась в том, что действительно было условие гонки, когда Flash пытался подключиться к сокету до получения файла политики. Итак, на внешнем интерфейсе я создал повторную попытку в обработчике ошибок безопасности, который будет запускаться заданное количество раз, прежде чем сдаться, а также установил тайм-аут по умолчанию, равный 20 секундам, до 6 или 8. Обычно он срабатывает на Попробуйте, и это помогло, но были времена, когда для подключения потребовалось бы 8-10 секунд, а не оптимальное решение.

Наткнулся на несколько ссылок в моих поисках, и в этом говорилось что-то о настройке задержки на сервере, 7-й пост: http://projectdarkstar.com/forum/?action=printpage;topic=1134.0

В конце мы скачали и использовали файловый сервер политик Python из этой статьи Adobe, и он работал безупречно, я не могу объяснить, почему, я не серверный парень, но это может стоить попытки:

хорошо, я могу опубликовать только 1 гиперссылку, так как я новый пользователь, странно. Ищите «Настройка файлового сервера политики сокетов», и он должен появиться, примеры файлов в этой статье на сайте Adobe.

1 голос
/ 26 ноября 2009

При отправке файла политики сервер должен всегда отправлять нулевой байт после политики xml. Из приведенного выше описания неясно, передан ли нулевой байт, и это может запутать Flash-проигрыватель.

1 голос
/ 21 ноября 2009

Случайно ... это происходит в Windows Vista? IP-адрес указан в качестве имени хоста? Если это так, см. это .

Или, может быть, это происходит, когда профилировщик активен? Если это так, см. это .

1 голос
/ 16 ноября 2009

попробуйте поставить пробел перед закрывающим тегом xml "/>", как в предложениях dan_nl, например:

Не смейтесь над этим, я только что решил проблему, очень похожую на вашу, вот так (и это действительно похоже на ошибку разбора ИМХО)

1 голос
/ 13 ноября 2009

Вы можете попробовать еще несколько вещей в коде с классом Security в дополнение к yoru crossdomain.xml

Попытка:

Security.allowDomain("*")
Security.allowInsecureDomain("*")

Или, если вы загружаете с внешних серверов за пределами разрешенного хоста:

Security.allowDomain(loader.contentLoaderInfo.url)

Затем медленно включите его, пока не нажмете ошибку.

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

Также в качестве простой проверки убедитесь, что вы назвали его crossdomain.xml, и все это в нижнем регистре. Я заставил программистов выдернуть свои волосы, и это оказалось причиной.

1 голос
/ 11 ноября 2009

Подобная проблема здесь указывает, что localhost не был разрешен до 127.0.0.1.

Вы можете попробовать перейти на IP-адрес и посмотреть, поможет ли это.

0 голосов
/ 07 декабря 2009

Я думаю, что Джеймс Уорд прав - я сейчас работаю с Сокетами и столкнулся с этой проблемой на днях. Я обнаружил сообщение, в котором говорится, что, если клиент Flash не закрывает сокет при отправке события COMPLETE, это может привести к появившейся ошибке. Я добавил код для закрытия клиентского сокета на ЗАВЕРШЕНИИ, и пока все работает нормально.

...