Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Socket (http://www.flasher.ru/forum/showthread.php?t=134574)

Ixanezis 05.01.2010 01:18

Socket
 
Люди, расскажите мне, я явно чего-то не понимаю.
Пишу многопользовательскую игру. И есть у меня сервер на джаве. Включен и ждёт себе мирно подключений.

На флеше заходит клиент, общается с ним по сокету и радуется.
Так вот когда я запускаю приложение в среде CS4, то всё классно работает и коннектится.
Потом, во-первых, если я запущу флешку не со среды, а просто с диска или в браузере, то выдаётся красивое сообщение:

SecurityError: Error #2010: Не допускается использование сокетов SWF-файлам в local-with-filesystem.

Один товарищ посоветовал почему-то написать во флешке
Security.loadPolicyFile("http://localhost/crossdomain.xml");
(Апач стоит, crossdomain.xml (что за он о_о) лежит где надо..)

Так вот после этого при запуске флешки с диска вылазит окошко, где написано, что Adobe Flash Player остановил потенциально небезопасную операцию с поддержкой интернета: localhost. В общем надо нажать параметры, чтобы разрешить. После этого в браузере врубается замечательная страничка

http://www.macromedia.com/support/do...anager04a.html

где, если выбрать этот swf-файл, то дальше всё работает хорошо.
Я в шоке, каким боком эта страничка к моему компу и почему она что-то разрешает тут делать О_о.

И во-вторых, ни у кого, кроме меня, такого сообщения ни возникает, однако игра не запускается. Просто ничего не происходит.

Эти все события взаимосвязаны? Кто-нибудь понимает, что происходит?
Огромнейшее спасибо, если проясните мне, что к чему..

alatar 05.01.2010 05:19

это называется политика безопасности

etc 05.01.2010 20:13

Научите ваш сервер отдавать кроссдоменник по сокету, по своему порту, а лучше по 843.

Ixanezis 06.01.2010 21:58

Ну.. Хорошо, спасибо, постараюсь с этим разобраться :)

Добавлено через 27 часов 48 минут
Так.. Я уже начал что-то понимать.
Скажите, а можно как-то узнать, загрузился ли crossdomain.xml успешно?
Просто я его загружаю уже сотней способов, но всегда один результат: при обращении к сокету вылазит:
text=Error #2048: Нарушение изолированной среды: http://domain/my.swf не может загрузить данные из ip:port.
ip:port - это java-сервер у меня на компе.


Цитата:

Научите ваш сервер отдавать кроссдоменник по сокету, по своему порту, а лучше по 843.
А можно подробней.? Как я научу сервер отдавать кроссдоменник, если при попытке к нему подключиться сразу возникает ошибка?

Добавлено через 47 часов 13 минут
Люди добрые!!
Ну скажите хоть что-нибудь!
Вы не знаете никто этого тоже?
Я уже часов 10 сижу над этим..... Оно не работает ну никак :(

andtsk 04.02.2010 16:53

Цитата:

Сообщение от etc (Сообщение 876960)
Научите ваш сервер отдавать кроссдоменник по сокету, по своему порту, а лучше по 843.

Тут имелось в виду что, при использовании именно SOCKET-ов необходимо отдавать кроссдоменник по тому же порту , куда свф-ка конектится. Но по дефолту она конектится на 843 порт, при неудаче лезет на порт сервера(т.е. куда она конектится).

P.S. после того как я последовал этому совету , у меня всё заработало.

nbid 20.07.2010 19:59

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

Вот флеш код:
Код:

package Lib
{
        import flash.display.Sprite;
        import flash.events.ProgressEvent;
        import flash.net.Socket;
        import flash.text.TextField;
        import flash.text.TextFieldType;
        import flash.utils.ByteArray;
        import flash.system.Security;

        public class SocketConnect extends Sprite
        {
  // Константы состояний для описания протокола
  public const VERSION:int = 0;
  public const AUTH:int = 1;
  public const WORKING:int = 2;
 
  // Сопоставляем состояние и функцию обработки
  private var stateMap:Object;
 
  // Отслеживаем текущее состояние протокола
  private var currentState:int;

  private var socket:Socket;
  private var field:TextField;

  public function SocketConnect()
  {
          field = new TextField();
          field.border = true;
          field.borderColor = 0xFF00FF;
          field.width = 600;
          field.height = 400;
          field.type = TextFieldType.DYNAMIC;
          addChild(field);

          field.appendText(' * Задача: Авторизироваться на сервере. * \n');
         
          // Сопоставляем состояния и константы состояний
          stateMap = new Object();
          stateMap[VERSION] = version;
          stateMap[AUTH] = auth;
          stateMap[WORKING] = working;
         
          // Инициализируем текущее состояние
          currentState = VERSION;

          try
          {
    socket = new Socket();
    socket.addEventListener(ProgressEvent.SOCKET_DATA, onSocketData);
    socket.connect('localhost', 843);
    field.appendText('Log: Соединение с сервером. \n');
          }
          catch(e:SecurityError)
          {
    field.appendText('Error: '+e+'.\n');
          }
  }

  private function onSocketData(event:ProgressEvent):void
  {
          field.appendText('Socket: Поступили данные состояния номер: "'+currentState+'".\n');
         
          // Ищем функцию обработки исходя из текущего состояния
          var processFunc:Function = stateMap[currentState];
          processFunc();
  }
 
  private function version():void
  {
          field.appendText('Log: Читаем версию с сервера\n');
         
          // Шаг 1 - читаем версию с сервера
          var version:int = socket.readInt();

          field.appendText('Chat: Версия: '+version+'\n');
         
          // Следующее состояние: Авторизация
          currentState = AUTH;
         
          field.appendText('Log: Запрашиваем авторизацию на сервере\n');
         
          // Шаг 2 - возвращаем версию на сервер
          socket.writeUTFBytes('auth|Nexus:xxxaaa');
          socket.flush();
  }
 
  // Авторизация
  private function auth():void
  {
          field.appendText('Log: Читаем результат авторизации\n');

          var string:String = socket.readUTFBytes(socket.bytesAvailable);
         
          if(string)
    field.appendText('Chat: Авторизация прошла успешно\n');
          else
    field.appendText('Chat: В авторизации отказано\n');
         
          // Следующее состояние: Начало работы
          currentState = WORKING;
         
          field.appendText('Log: Запрашиваем данные\n');

          socket.writeUTFBytes('getData');
          socket.flush();
  }
 
  // Начало работы
  private function working():void
  {
          field.appendText('Log: Получаем данные\n');

          var string:String = socket.readUTFBytes(socket.bytesAvailable);
         
          field.appendText('Chat: '+string+'\n');

          // Завершаем работу сокета
          socket.close();
         
          field.appendText(' * Задача выполнена, сокет закрыт. * \n');
  }
        }
}

Вот PHP сервер (комменты будут глупо выглядеть т.к. переводил через гугл транслейт:

Код:

#!/usr/local/bin/php
<?php
// Порт подключения
$port = 843;
$ip = '78.46.98.68';

// Создаёт конечную точку соединения (сокет) и возвращает ресурс сокета
// Тип подключения TCP/IP
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

// Опции сокета:
socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1); // Отсчеты либо локальные адреса могут быть использованы повторно

// Связать адрес и порт с сокетом
socket_bind($socket, 0, $port);

// Начать прослушивать соединение на сокете
socket_listen($socket);
       
// Создать список всех клиентов, которые будут связаны с нами
// Добавить сокет к этому списку
$clients = array($socket);

while(true)
{
        sleep(1); // Задержка
       
        // создать копию что бы $clients не получила изменения socket_select()
        $read = $clients;
 
        // Получить список всех клиентов, которые имеют данные, которые будут читать
        // Если нет клиентов с данными, перейти к следующей итерации
       
        // Принимает массивы сокетов и ожидает их для изменения статуса
        if(socket_select($read, $write = NULL, $except = NULL, 0) < 1) continue;
 
        // Проверить, есть ли клиент, пытающийся установить соединение
        if(in_array($socket, $read))
        {
  // Принять клиента, и добавить его в массив $clients
  $clients[] = $newsock = socket_accept($socket);

  // Отправить клиенту приветствие
  socket_write($newsock, "Привет клиент! Ты приконнектился к серверу;)\nСейчас онлайн ".(count($clients) - 1)." клиентов\n");
  //socket_write($newsock, "Hello\n");

  // Запросить удалённую сторону данного сокета, чтобы получить пару host/port
  socket_getpeername($newsock, $client_ip);
 
  // Написать в SSH оповещение
  echo "New client connected: {$client_ip}\n";
   
  // Удалить сокет от клиентов с массива данных
  unset($read[array_search($socket, $read)]);
        }

        // Цикл по всем клиентам, которые имеют данные для чтения
        foreach($read as $read_sock)
        {
  // Читать новую строку или до 1024 байтов
  $data = @socket_read($read_sock, 1024, PHP_BINARY_READ);
   
  // Если клиент отключился
  if($data === false)
  {
          // Удалить клиента из массива $clients
          unset($clients[array_search($read_sock, $clients)]);
         
          // Написать в SSH оповещение
          echo "client disconnected.\n";
         
          // Переход к следующему клиенту
          continue;
  }

  // Очистить пробелы по краям
  $data = trim($data);
  echo $data."\n";

  if($data == '<policy-file-request/>')
  {

          $return = "<?xml version=\"1.0\"?>"
      ."<!DOCTYPE cross-domain-policy SYSTEM \"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd\">"
      ."<cross-domain-policy>"
      ."<allow-access-from domain=\"*\" secure=\"true\" to-ports=\"*\" />"
      ."</cross-domain-policy>\n";

      /*
          $sreturn =
      '<'.'?xml version="1.0" encoding="UTF-8"?'.'>'.
      '<cross-domain-policy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.adobe.com/xml/schemas/PolicyFileSocket.xsd">'.
          '<allow-access-from domain="*" to-ports="*" secure="false" />'.
          '<site-control permitted-cross-domain-policies="master-only" />'.
      '</cross-domain-policy>';
          */
         
          foreach($clients as $send_sock)
          {
    @socket_write($send_sock, $return);
          }
         
          echo "Police file sended...\n";
         
          continue;
  }

  // Проверить, есть ли данные после обрезки от пространства
  if(!empty($data))
  {
          $data = explode('|',$data);
          $command = $data[0];
          $text = $data[1];
         
          // Команды
          $return = '';
          switch($command)
          {
    case 'auth': $return = 'Запрос авторизации'; break;
    case 'getData': $return = 'Различные данные из базы данных'; break;
    default: $return = 'Нет запроса'; break;
          }

          // Оповестить о входящих данных
          echo "Data accept ".iconv('utf-8', 'cp866', $command.' - '.$return)."\n";
          //echo "Data accept ".$command." - ".$return."\n";
         
          // Послать данные для всех клиентов в массиве $clients, за исключением первого, чей сокет
          foreach($clients as $send_sock)
          {
    // Если это тот чей сокет - перейти к следующему
    #if($send_sock == $socket || $send_sock == $read_sock) continue;
     
    // Написать сообщение для клиента и добавить символ новой строки в конец сообщения
    @socket_write($send_sock,"{$return}");
          }
   
  }
   
        }
}

// Закрыть сокет
socket_close($socket);
?>

Если запускаю из Abobe Flash CS4 то получаю следующее:
Цитата:

* Задача: Авторизироваться на сервере. *
Log: Соединение с сервером.
Socket: Поступили данные состояния номер: "0".
Log: Читаем версию с сервера
Chat: Версия: -794832512
Log: Запрашиваем авторизацию на сервере
Socket: Поступили данные состояния номер: "1".
Log: Читаем результат авторизации
Chat: Авторизация прошла успешно
Log: Запрашиваем данные
Socket: Поступили данные состояния номер: "2".
Log: Получаем данные
Chat: Различные данные из базы данных
* Задача выполнена, сокет закрыт. *
А в шелле:
Цитата:

New client connected: 127.0.0.1
auth|Nexus:xxxaaa
Data accept auth - Запрос авторизации
getData
Data accept getData - Различные данные из базы данных
А если запускаю отдельно, то получаю следующее (не работает):
Цитата:

* Задача: Авторизироваться на сервере. *
Log: Соединение с сервером.
А в шелле:
Цитата:

New client connected: 127.0.0.1
<policy-file-request/>
Police file sended...
client disconnected.
client disconnected.
(два диссконекта наверно из-за того что предыдущий еще не дисконнектился.

Local Playback security стоит - Access network only

А если ставлю Access local files only
то когда запускаю из флеша - все также, а когда запускаю отдельно, то флешка показывает этот текст:

Цитата:

* Задача: Авторизироваться на сервере. *
Error: SecurityError: Error #2010.
и Шелл при этом вообще нечего не выводит.

Если будете помогать и отвечать, скажите что в "Local Playback security" должно стоять, если РНР сервер и сама флешка будет лежать на одном и том же сервере.

Так вот, в чем моя проблема? Объясните пожалуйста :) Я больше не могу с этим жить! :)
очень благодарю тех кто решит помочь :)

nbid 20.07.2010 20:00

(отредактировать предыдущее сообщение нельзя т.к. не влезает более 10 000 символов) остаток того что хотел сказать:

У меня судя по всему не отдается из РНР сервера файл политики, может я как то не правильно это делаю? (см в коде), может надо заголовки какие нибудь еще прибавлять? оО, а то получается что я только "содержимое файла" передаю.... что только не пробовал.

mikhailk 20.07.2010 21:10

Цитата:

Сообщение от andtsk (Сообщение 884089)
Тут имелось в виду что, при использовании именно SOCKET-ов необходимо отдавать кроссдоменник по тому же порту , куда свф-ка конектится. Но по дефолту она конектится на 843 порт, при неудаче лезет на порт сервера(т.е. куда она конектится).

Опытным путем установлено, что файл политики можно отдавать с любого порта. :)

nbid 20.07.2010 21:25

ну это очень старые сообщения, мое - новое :)

gloomyBrain 20.07.2010 21:29

Цитата:

Опытным путем установлено, что файл политики можно отдавать с любого порта.
Как-то странно, ибо на оном хосте может висеть чей-то сайт и мой JAVA-сервер, раздающий по 843-порту дозволения творить любой беспредел с этим сайтом... Пойду еще почитаю, только сейчас об этом задумался =)


Часовой пояс GMT +4, время: 06:38.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.