2010-08-03 5 views
3

Il existe un film Flash qui utilise flash.net.Socket pour se connecter à un serveur. Mais il pourrait y avoir une situation où le serveur ne fonctionne pas, donc rien n'est écouté sur le port auquel se connecte.Y at-il un moyen de détecter que la connexion TCP a été refusée en utilisant flash.net.Socket?

Lorsque je fais "telnet hostname port", j'obtiens une erreur de connexion rapide refusée. Mais flash.net.Socket n'appelle aucun événement (voir ci-dessous), mais attend silencieusement le délai d'expiration du socket. Pour moi, il est important de réduire autant que possible le temps nécessaire pour détecter le serveur inexistant afin de pouvoir se reconnecter à un autre serveur du cluster.

J'ai essayé les événements suivants, mais en vain:

  • près
  • connecter
  • ioError
  • securityError
  • socketData

Aucun d'entre eux est invoqué dans une telle situation.

Y at-il un moyen de détecter que la connexion TCP a été refusée en utilisant flash.net.Socket?

Répondre

0

Qu'en est-il des erreurs de connexion catch avec ajouter <img src='http://target:port/' onerror='noconnect' />?

+0

Est-ce que onerror est pris en charge dans tous les navigateurs? Est-il déclenché lorsque le serveur ne renvoie rien? – gleber

+0

Oui, le mieux est que le serveur puisse répondre avec une réponse vide sur GET/- puis, les appels successifs sont appelés. http://www.w3schools.com/jsref/event_img_onerror.asp - ressemble à onerror pris en charge dans tous les navigateurs. au moins à l'opéra/iceweasel/ie ça marche pour moi. – datacompboy

+0

Merci pour une suggestion, mais cela semble être seulement une solution de contournement. Je vais attendre un peu plus. Peut-être existe-t-il une vraie solution? – gleber

0

Qu'en est celui-ci:

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

Il est basé sur un court délai, n'est-ce pas? Il ne convient pas pour moi, car parfois le serveur peut être lourdement chargé et le délai d'attente est trop court – gleber

+0

et si nous modifions l'architecture du serveur? Ecrivez un vérificateur de serveur externe, qui vérifiera l'état d'exécution du serveur, et répondra de la disponibilité du cloud. Qu'est-ce que tu penses? Comme un style SLA – Eugene

+0

Cet exemple a été copié textuellement depuis la [page doc Adobe] (http://help.adobe.com/fr_FR/FlashPlatform/reference/actionscript/3/flash/net/Socket.html), et le 100ms timeout a été ajouté. La propriété de délai d'attente est uniquement Flash 10+, et cela n'aidera pas dans ce cas de toute façon. Le problème avec l'exemple est en fait le même que celui que je décris ci-dessus: les écouteurs ne sont pas ajoutés tant que le constructeur n'a pas initié la tentative de connexion - donc les erreurs de connexion rapide peuvent être complètement oubliées. Vous pouvez éviter ce problème en utilisant le constructeur no-args, suivi d'un appel à 'connect (host, port)'. – Lee

0

La clé est d'écouter l'objet Socket pour l'événement IOErrorEvent.IO_ERROR. Dans le cas où vous faites référence, où la connexion est refusée immédiatement, cet événement sera déclenché immédiatement. En fait, il peut être déclenché si rapidement que vous le manquer, sauf si vous faites les choses dans le bon ordre (comme indiqué ici):

// 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); 

NOTE: cette approche est pas basée sur un délai d'attente. Si le serveur renvoie une réponse définie "connexion refusée", l'événement Erreur E/S se produit immédiatement lorsque cette réponse est reçue.

Le délai d'expiration s'applique uniquement lorsque le serveur ne renvoie rien pendant une période prolongée. Cela peut arriver avec certaines configurations serveur/pare-feu qui en fait abandonnent les paquets en silence plutôt que de retourner "connection refused". Lorsque cela se produit, le client (dans ce cas, Flash) attendra que le délai expire. Lorsque le délai expire, il en résulte un événement IOErrorEvent.IO_ERROR comme prévu.

Le délai d'attente de socket par défaut dépend de la plate-forme, mais il est toujours assez long (~ 20-30 secondes ou plus). La propriété Socket.timeout est présentée dans Flash Player version 10 et Air 1.0. Pour autant que je sache, il n'y a aucun moyen d'ajuster le délai de socket en utilisant ActionScript avant Flash Player 10.

bonne chance!

--- EDIT: si elle ne fonctionne toujours pas, poursuivez votre lecture ---

Vous devez également connaître la façon dont le lecteur flash cherche (et nécessite) un fichier de stratégie de prise.Les fichiers de stratégie de socket manquants ou endommagés peuvent parfois produire un comportement qui ressemble à un socket en attente de délai. Je cite this Adobe Document:

accès à socket et connexions socket XML est désactivé par défaut, même si la prise vous connectez est dans le même domaine que le fichier SWF. Vous pouvez autoriser la prise de niveau accès en servant un fichier de stratégie de prise de l'un des endroits suivants:

  • Port 843 (l'emplacement du fichier de stratégie maître)
  • Le même port que la connexion principale de prise
  • un autre port que la connexion socket principale

Cela signifie que, à moins que vous avez déjà chargé un fichier de stratégie à l'aide Security.loadPolicyFile(), lorsque vous essayez d'abord de se connecter votre socket sur le serveur, flash va d'abord essayer de résoudre un fichier de politique. Dans certains cas, cela peut entraîner des retards de connexion étranges ou d'autres comportements inattendus. Si vous pensez que vous rencontrez ce problème, vous devez commencer par ajouter un écouteur pour flash.events.SecurityErrorEvent.SECURITY_ERROR.

Questions connexes