Есть ли способ определить, что в TCP-соединении было отказано с помощью flash.net.Socket? - PullRequest
3 голосов
/ 03 августа 2010

Существует флэш-фильм, который использует flash.net.Socket для подключения к серверу.Но может быть ситуация, когда сервер не работает, следовательно, ничего не прослушивается через порт, к которому подключается сокет.

Когда я делаю "порт имени хоста telnet", я получаю сообщение об ошибке быстрого отказа в соединении.Но flash.net.Socket не вызывает никакого события (см. Ниже), но молча ожидает истечения времени ожидания сокета.Для меня важно максимально сократить время, необходимое для обнаружения несуществующего сервера, чтобы иметь возможность повторно подключиться к другому серверу в кластере.

Я пробовал следующие события, но безрезультатно:

  • close
  • connect
  • ioError
  • securityError
  • socketData

Ни один из этихвызывается в такой ситуации.

Есть ли способ определить, что TCP-соединение было отклонено с помощью flash.net.Socket?

Ответы [ 3 ]

0 голосов
/ 07 сентября 2010

что насчёт этого:

package {
    import flash.display.Sprite;

    public class SocketExample extends Sprite {

        public function SocketExample() {
            var socket:CustomSocket = new CustomSocket("localhost", 80);
        }
    }
}

import flash.errors.*;
import flash.events.*;
import flash.net.Socket;

class CustomSocket extends Socket {
    private var response:String;

    public function CustomSocket(host:String = null, port:uint = 0) {
        super(host, port);
        this.timeout=100;
        configureListeners();
    }

    private function configureListeners():void {
        addEventListener(Event.CLOSE, closeHandler);
        addEventListener(Event.CONNECT, connectHandler);
        addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
        addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
        addEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler);
    }

    private function writeln(str:String):void {
        str += "\n";
        try {
            writeUTFBytes(str);
        }
        catch(e:IOError) {
            trace(e);
        }
    }

    private function sendRequest():void {
        trace("sendRequest");
        response = "";
        writeln("GET /");
        flush();
    }

    private function readResponse():void {
        var str:String = readUTFBytes(bytesAvailable);
        response += str;
    }

    private function closeHandler(event:Event):void {
        trace("closeHandler: " + event);
        trace(response.toString());
    }

    private function connectHandler(event:Event):void {
        trace("connectHandler: " + event);
        sendRequest();
    }

    private function ioErrorHandler(event:IOErrorEvent):void {
        trace("ioErrorHandler: " + event);
    }

    private function securityErrorHandler(event:SecurityErrorEvent):void {
        trace("securityErrorHandler: " + event);
    }

    private function socketDataHandler(event:ProgressEvent):void {
        trace("socketDataHandler: " + event);
        readResponse();
    }
}
0 голосов
/ 12 сентября 2010

Ключ заключается в прослушивании объекта Socket для события IOErrorEvent.IO_ERROR.В случае, если вы имеете в виду, что в соединении немедленно отказано, это событие будет немедленно запущено .На самом деле, он может быть запущен так быстро, что вы пропустите его, если не будете делать все в правильном порядке (как показано здесь):

// first create the unconnected socket, and add the listener
// you *must* add the listener *before* connecting the socket
//
var mySocket = new Socket();
mySocket.addEventListener(IOErrorEvent.IO_ERROR, function(event:IOErrorEvent):void {
    // called when error occurrs
    trace("ioErrorHandler: " + event);
});
mySocket.addEventListener(flash.events.Event.CONNECT, function(event:Event):void {
    // handle a successful connection here
    //...
});

// now initiate the connection to port 80 on "server.example.com"   
mySocket.connect( 'server.example.com', 80 );

ПРИМЕЧАНИЕ: этот подход основан на , а не на тайм-аут.Если сервер возвращает определенный ответ «отказано в соединении», то событие IO Error произойдет сразу же после получения этого ответа.

Тайм-аут применяется только тогда, когда сервер ничего не возвращает в течение длительного периода времени.Это может произойти с некоторыми конфигурациями сервера / брандмауэра, которые на самом деле отбрасывают пакетов молча, а не возвращают «отказано в соединении».Когда это происходит, клиент (в данном случае Flash) будет сидеть в ожидании истечения времени ожидания.Когда тайм-аут действительно истекает, это приведет к событию IOErrorEvent.IO_ERROR, как и следовало ожидать.

Тайм-аут сокета по умолчанию зависит от платформы, но он всегда довольно длинный (~ 20-30 секунд или более).Свойство Socket.timeout введено в Flash Player версии 10 и Air 1.0.Насколько я знаю, нет способа отрегулировать время ожидания сокета с помощью ActionScript до Flash Player 10.

удачи!

--- EDIT: если он все еще не работает,читайте дальше ---

Вы также должны быть знакомы с тем, как флэш-плеер ищет (и требует) файл политики сокетов.Отсутствующие или поврежденные файлы политики сокетов могут иногда вызывать поведение, похожее на сокет, ожидающий по таймауту.Цитирование этого документа Adobe :

Доступ к сокетам и соединениям с сокетами XML по умолчанию отключен, даже если сокет, к которому вы подключаетесь, находится в том же домене, что и SWF-файл.,Вы можете разрешить доступ на уровне сокетов, передав файл политики сокетов из любого из следующих расположений:

  • Порт 843 (расположение основного файла политики)
  • Тот же порт, что иподключение к главному сокету
  • Порт, отличный от подключения к главному сокету

Это означает, что, если вы предварительно не загрузили файл политики с помощью Security.loadPolicyFile(), когда вы изначальнопопробуйте подключить сокет к серверу, флэш сначала попытается разрешить файл политики.В некоторых случаях это может привести к странным задержкам соединения или другому непредвиденному поведению.Если вы считаете, что можете столкнуться с этой проблемой, вам следует начать с добавления прослушивателя для flash.events.SecurityErrorEvent.SECURITY_ERROR.

0 голосов
/ 08 августа 2010

Как насчет перехвата ошибок соединения с добавлением <img src='http://target:port/' onerror='noconnect' />?

...