Почему в этом случае Flash Player выдает ошибку песочницы?

Я получаю ошибку песочницы Flex 3 # 2048 после подключения к Socket на сервере 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 player выдает ошибку песочницы 2048 и сокет отключается! Это после получения и успешной обработки сообщения. На самом деле это примерно через 12 секунд. Больше через розетку ничего не работает.

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

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

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

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

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

ИЗМЕНИТЬ В ответ на запрос Джеймса Варда в его комментарии, вот полное сообщение об ошибке:

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;[email protected];Si
Receiving: REG:0/REGISTER:SUCCESS;[email protected];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.

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

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

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


person Simon    schedule 10.11.2009    source источник
comment
Есть ли какие-либо дополнительные сведения, записанные во флэш-журнал или журнал файлов политик? Если да, можете ли вы добавить точные сообщения?   -  person Michael Brewer-Davis    schedule 12.11.2009
comment
во флешлоге есть сообщение, в котором говорится, что swf загружается, но это все для журнала политики, я все это показал дословно.   -  person Simon    schedule 12.11.2009
comment
Вы можете опубликовать все сообщение об ошибке?   -  person James Ward    schedule 30.11.2009
comment
Можете ли вы загрузить свой тестовый исходный код с ошибкой FP-3302?   -  person James Ward    schedule 01.12.2009
comment
@ Джеймс, готово. Я поместил свой серверный код и самый простой клиент, который я мог сделать в zip-архиве, и приложил его к проблеме.   -  person Simon    schedule 01.12.2009


Ответы (9)


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

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

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

person James Ward    schedule 04.12.2009
comment
_in и _out - это просто потоки печати, которые следует закрыть, но _socket - это TCP-сокет, возвращаемый SocketServer, прослушивающим порт 843. Я закомментирую все close и посмотрю, что произойдет. Большое спасибо, что посмотрели на это. - person Simon; 06.12.2009
comment
Прогресс! Я больше не получаю ошибку песочницы, но сокет тоже больше не работает, поэтому второе и последующие сообщения, отправленные через него, не попадают на сервер. Я продолжаю расследование, но это похоже на шаг вперед. Спасибо, Джеймс. - person Simon; 08.12.2009
comment
По какой-то причине я все еще получал событие закрытия даже после того, как закомментировал строку _socket.close (). Не знаю, почему это закроется. Странный. - person James Ward; 08.12.2009

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

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

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

<allow-access-from domain="*" to-ports="843,45455" />
person dan_nl    schedule 14.11.2009
comment
Я безуспешно пытался указать порты. Первый не применим, так как спецификация файла политики сокетов не требует тега. Помните, я не делаю HTTP-запросы, я иду прямо на порт с двоичным сокетом. adobe.com/devnet/flashplayer/articles/socket_policy_files.html - person Simon; 15.11.2009
comment
Вот как файл policyfiles.txt выглядит нормально: поиск ‹allow-access-from› в файлах политики для авторизации загрузки данных из ресурса в xmlsocket: //192.168.2.3: 45455 отправителем запроса из localhost / bst / BasicSocketTest.swf Предупреждение: игнорирование недопустимого тега ‹allow-http-request-headers-from› для домена '*' в файле политики в xmlsocket: //192.168.2.3: 843 OK: файл политики принят: xmlsocket: //192.168.2.3: 843 OK: Запрос ресурса в xmlsocket: //192.168.2.3: 45455 отправителем запроса от localhost / bst / BasicSocketTest.swf разрешен из-за файла политики в xmlsocket: //192.168.2.3: 843, затем 2048 - person Simon; 15.11.2009
comment
Это странно в отношении allow-http-request-headers-from, поскольку он следует за dtd и примером - kb2.adobe.com/cps/403/kb403185.html; Эта одна строка и указание фактических портов помогли в предыдущем проекте. Это может быть тривиально, но добавили ли вы локальную папку в настройки глобальной безопасности macromedia.com/support/documentation/en/flashplayer/help/? - person dan_nl; 15.11.2009
comment
У вас была возможность дважды проверить настройки глобальной безопасности? macromedia.com/support/documentation/en/flashplayer/help/ - person dan_nl; 29.11.2009

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

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

person Phil Hayward    schedule 10.11.2009
comment
спасибо за предложение, но я использую только IP-адреса при привязке сокета, поэтому разрешение localhost в другом потоке неприменимо - person Simon; 11.11.2009
comment
Верно, но в выходном журнале написано localhost / bst / BasicSocketTest.swf Другой способ проверить это, чтобы включить публичный сервер где-нибудь и проверьте этот URL, а не с localhost. - person Ryan Christensen; 13.11.2009

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

Пытаться:

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

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

Security.allowDomain(loader.contentLoaderInfo.url)

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

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

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

person Community    schedule 12.11.2009
comment
спасибо за предложения кода, я попытался добавить оба в свой код и получил ту же ошибку песочницы. Мой сервер успешно открывает 843 и 45455, поэтому у меня нет проблем с блокировкой портов. Как я говорю в своем вопросе, первое сообщение проходит, чего бы не произошло, если бы сокеты не работали. Также я не использую HTTP, поэтому crossdomain.xml не имеет значения, поскольку игрок ищет главный файл политики сокета на порту 843. Это работает, и я обслуживаю открытый файл политики. Я все еще получаю ошибку песочницы. adobe.com/devnet/flashplayer/articles/fplayer9_security_04.html - person Simon; 13.11.2009

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

‹Allow-access-from domain =" * "/›

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

person Luca Bortot    schedule 16.11.2009

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

А может это происходит при активном профилировщике? Если да, см. это .

person wallyk    schedule 21.11.2009
comment
Спасибо, но нет, XP. Вашу первую ссылку тоже опубликовал @Phil Hayward. Я не могу сказать наверняка, что это никуда не исчезнет в общедоступном Интернете, и я собираюсь арендовать общедоступный сервер, чтобы опробовать его - дорогостоящее расследование ошибок. В игре нет профилировщика. - person Simon; 21.11.2009

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

person Vladimir Grigorov    schedule 26.11.2009
comment
Я знал о нулевом завершающем байте и пробовал его без какого-либо эффекта. Однако я попробовал это с некоторыми другими изменениями, так что, возможно, я попробую еще раз. Спасибо за Ваш ответ. - person Simon; 28.11.2009

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

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

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

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

person Duncan    schedule 01.12.2009
comment
это очень полезный пример, большое спасибо. Я немного изменю код сервера, чтобы попробовать некоторые из этих вещей. Как изменить тайм-аут? - person Simon; 02.12.2009
comment
надеюсь, вам требуется Flash 10, кажется, именно тогда он был представлен: help.adobe.com/en_US/AS3LCR/Flash_10.0/flash/net/ - person Duncan; 02.12.2009
comment
Я попробовал то же самое, что и OP в этом потоке, то есть добавил задержку и убедился, что сокет закрывается на стороне сервера, и я получаю немного разные тайминги, но тот же конечный результат. Я должен был указать версию флеш-плеера в исходном вопросе - спасибо, что указали на это, я внесу правку. - person Simon; 02.12.2009

Я думаю, что Джеймс Уорд прав - сейчас я работаю с Sockets и на днях столкнулся с этой проблемой. Я нашел сообщение, в котором говорилось, что если клиент Flash не закрывает Socket при отправке события COMPLETE, это может привести к ошибке, которую вы видите. Я добавил код для закрытия клиентского Socket на COMPLETE, и пока все работает нормально.

person Maciek Sakrejda    schedule 07.12.2009
comment
Это интересно, если немного озадачить. Итак, вы создаете новый клиентский сокет для каждого запроса? Я улавливаю все события, которые исходят из клиентского сокета, и я вообще не получаю событие COMPLETE - на самом деле я не могу точно определить, какое событие может быть, вы можете дать точную информацию о событии? Я обрабатываю данные в событии ProgressEvent.SOCKET_DATA, запущенном сокетом. - person Simon; 08.12.2009