PDA

Просмотр полной версии : sockets + apache + php


Anton_sz
14.09.2011, 18:24
Приветствую. Недавно начал работать с as3 и не могу решить одну задачу:
Нужно из flash передать данные для php скрипта и получить от него ответ, причем сделать это нужно через socket. Причем флешка будет грузиться на одном домене, а скрипт будет находиться на другом.
Вот код as3
import flash.display.Sprite;
import flash.events.Event;
import flash.events.TextEvent;
import flash.net.Socket;
import flash.text.TextField;
import flash.text.TextFieldType;
import flash.events.ProgressEvent;
import flash.system.Security;

public class Main extends Sprite
{
private var mySocket:Socket;
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}

private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
var field:TextField = new TextField();
field.border = true;
field.x = 10;
field.y = 10;
field.borderColor = 0xCCC;
field.width = 780;
field.height = 580;
field.type = TextFieldType.DYNAMIC;
addChild(field);

mySocket = new Socket();
mySocket.addEventListener(Event.CONNECT, onConnect);
function onConnect(success:Event):void {
if (success) {
field.appendText("Server connection established!\n");
} else {
field.appendText("Server connection failed!");
}
};

mySocket.addEventListener(ProgressEvent.SOCKET_DATA, onData);
function onData(event:ProgressEvent):void {
field.appendText(mySocket.readUTFBytes(mySocket.bytesAvailable));
};


Security.loadPolicyFile("socket://localhost:80");
mySocket.connect("localhost", 80);
var str:String;

str += "GET /index.php?test=text HTTP/1.0\r\n";
str += "Host:localhost\r\n";
str += "User-Agent:Mozilla/5.0 (Windows NT 6.1; rv:6.0.2) Gecko/20100101 Firefox/6.0.2\r\n";
str += "Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n";
str += "Accept-Language:ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3\r\n";
str += "Accept-Encoding:gzip, deflate\r\n";
str += "Accept-Charset:windows-1251,utf-8;q=0.7,*;q=0.7\r\n";
str += "Connection:keep-alive\r\n\r\n";
mySocket.writeUTFBytes(str);
}
Локально все работает. Но когда запускаю флешку с другого домена то не робит.
Вот файл crossdomain.xml:
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<site-control permitted-cross-domain-policies="master-only"/>
<allow-access-from domain="*" to-ports="80,8080" />
</cross-domain-policy>
Скрипт пхп работает правильно, к нему вопросов нет.
Помогите найти ошибку.
P.S. я новичок в as3. не ругайте сильно, если что не так.

dimarik
15.09.2011, 10:01
Вот файл crossdomain.xml:

Сокет не имеет никакого отношения к файлам политик (http://www.adobe.com/devnet/flashplayer/articles/flash_player10_security_wp.html).

Anton_sz
15.09.2011, 10:42
Вы ошибаетесь. Вот что сказано про это на help.adobe.com (http://help.adobe.com/ru_RU/ActionScript/3.0_ProgrammingAS3/WS5b3ccc516d4fbf351e63e3d118a9b90204-7e08.html):
Так как проигрыватель Flash Player поддерживает два типа подключений к серверу, существует и два типа файлов политики: файлы политики URL-адресов и файлы политики сокетов.

Для подключений на основе документов требуются файлы политики URL-адресов. С помощью этих файлов сервер указывает, что его данные и документы доступны для SWF-файлов, размещенных на определенных доменах или на любых доменах.
Для подключений к сокетам требуются файлы политики сокетов, которые обеспечивают прямое сетевое подключение к TCP-сокетам нижнего уровня с помощью классов Socket и XMLSocket.

wvxvw
15.09.2011, 13:34
Если соединение делается с использованием классов Socket / XMLSocket, то сразу после соединения либо на порт по умолчанию (забыл какой, но это случайно тот же порт, что Apache использует для SSL), либо на тот же порт, куда вы хотите подключится высылается запрос на получение политик безопасности. Ответ на этот запрос должен выглядеть как содержание файла crossdomain.xml, но наличие файла никак вам не поможет, потому что оно, само по себе никак не связано с открытием порта на том же IP, в то время как программа открывшая порт наверняка уж знает можно или нельзя подключатся.
Вы так же можете указать для определенноги IP в каком порту получать политики безопасности, делается это через Security.loadPolicyFile("xmlsocket://{IP}:{port}");.

dimarik
15.09.2011, 13:53
Вы ошибаетесь. Вот что сказано про это на...

Наверное, я неясно выразился. Файл (http://ru.wikipedia.org/wiki/%D0%A4%D0%B0%D0%B9%D0%BB) (файл — поименованная последовательность байтов) в организации доступа по сокету непосредственно может не участвовать. Это может быть xml-like строка в недрах сокет-сервера. И да, вообще crossdomain.xml — это дефолтный файл для разграничения доступа по http(s). Что легко выясняется по предоставленному whitepaper.

Anton_sz
15.09.2011, 14:22
Спасибо, помогло. Остался еще один вопрос.
При помощи Security.loadPolicyFile("xmlsocket://test.ru:843"); я забираю файл политик. 843 порт слушает скрипт и отдает этот самый файл.
Если запускать флешку из браузера, то соединение с apache устанавливается, но запрос к скрипту не отсылается.
В логах все чисто:
ОК: Выполнена загрузка SWF-файла корневого уровня: http://www.test1.ru/sockets.swf
ОК: Выполняется поиск директив <allow-access-from> в файлах политики, чтобы авторизовать загрузку данных из ресурса по адресу xmlsocket://test.ru:843 инициатором запроса из http://www.test1.ru/sockets.swf
ОК: Файл политики принят: xmlsocket://test.ru:843
ОК: Запрос ресурса на xmlsocket://test.ru:843 источника запроса из http://www.test1.ru/sockets.swf разрешен согласно файлу политики на xmlsocket://test.ru:843

пробовал после mySocket.writeUTFBytes(str);
делать mySocket.flush(), но не помогло.

Причем, если запускать скрипт из flashdevelop, то все работает.
Где я опять ошибся?

Добавлено через 8 минут
Проблему решил. :) сделал отправку данных в событии
function onConnect(success:Event):void {
if (success) {
field.appendText("Server connection established!\n");
this.sock.writeUTFBytes( "request" );
this.sock.flush();
} else {
field.appendText("Server connection failed!");
}
};

И все заработало!
Спасибо за помощь!
Жаль здесь нельзя плюсик в карму поставить :)

Aquahawk
15.09.2011, 14:39
Жаль здесь нельзя плюсик в карму поставить
Можно, справа сверху у каждого сообщения есть весы, там и можно.

Anton_sz
15.09.2011, 14:53
поставил :)

Aquahawk
15.09.2011, 15:04
а мне?:rolleyes:

dimarik
15.09.2011, 15:20
Спасибо, помогло. Остался еще один вопрос.
При помощи Security.loadPolicyFile("xmlsocket://test.ru:843"); я забираю файл политик. 843 порт слушает скрипт

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

А да, вот оно в whitepaper.

Security.loadPolicyFile()
A policy file allows administrators to grant an application read access to specific server locations (URL policy
files) or to specific port numbers (socket policy files). The default URL policy file is named crossdomain.xml
and is located in the root directory of the target server. The default socket policy file is served from port 843.

Anton_sz
15.09.2011, 16:11
Вы абсолютно правы. просто на сервере порт другой, а у меня на локалке по умолчанию.
А можно еще вопрос.
Я хочу написать класс, который бы был оберткой класса Socket. Хочу сделать метод send, который будет отправлять запрос и возвращать результат ответа. Подтолкните в сторону, где копать?
Ведь там надо будет дождаться когда сокет подконнектится.. чтобы не посылать запрос до того как произойдет подключение.
P.S.
И куда глядеть, чтобы обратиться к ресурсу по протоколу https. Это для меня более интересно.