SoquetesFlash Player 9 e posterior, Adobe AIR 1.0 e posterior Um soquete é um tipo de conexão de rede estabelecida entre dois processos de computador. Geralmente, os processos são executados em dois computadores diferentes, conectados na mesma rede de Protocolo de Internet (IP). No entanto, os processos conectados podem ser executados no mesmo computador, utilizando o endereço IP especial “local host”. O Adobe Flash Player oferece suporte a soquetes de Protocolo de Controle de Transporte (TCP) do lado do cliente. Um aplicativo Flash Player pode conectar a outro processo, atuando como servidor de soquete, mas não pode aceitar solicitações de conexões de entrada de outros processos. Em outras palavras, um aplicativo Flash Player pode se conectar a um servidor TCP, mas não pode agir como um. A API do Flash Player também inclui a classe XMLSocket. A classe XMLSocket utiliza um protocolo específico do Flash Player que permite a troca de mensagens XML com um servidor compatível com o protocolo. A classe XMLSocket foi introduzida no ActionScript 1 e ainda possui suporte para fornecer compatibilidade com a versão anterior. No geral, a classe Socket pode ser utilizada para aplicativos novos, a não ser que você esteja estabelecendo uma conexão com um servidor especificamente criado para comunicar-se com Flash XMLSockets. O Adobe AIR adiciona diversas classes para programação de rede com base em soquetes. Aplicativos AIR podem agir como servidor de soquete TCP com a classe ServerSocket e podem conectar-se a servidores de soquete que requerem segurança SSL ou TLS com a classe SecureSocket. Os aplicativos AIR também podem enviar e receber mensagens de Protocolo de Datagrama Universal (UDP) com a classe DatagramSocket. Soquetes TCPO protocolo de controle de transmissão (TCP) fornece uma maneira de trocar mensagens em uma conexão de rede permanente. O TCP garante que as mensagens enviadas cheguem na ordem correta (salvo quando ocorrem problemas de rede). As conexões TCP requerem um cliente em um servidor. O Flash Player pode criar soquetes de cliente. O Adobe AIR pode, além disso, criar soquetes de servidor. As APIs de ActionScript a seguir fornecem conexões TCP:
Soquetes binários de clienteUma conexão de soquete binário é semelhante a um soquete XML, exceto que o cliente e o servidor não ficam limitados à troca de mensagens XML. Em vez disso, a conexão pode transferir dados como informações binárias. Assim, você pode se conectar a uma gama maior de serviços, incluindo servidores de email (POP3, SMTP e IMAP) e novos servidores (NNTP). classe SocketA classe Socket permite que você faça conexões de soquete e leia e grave dados binários brutos. A classe Socket é útil para interoperar com servidores que usam protocolos binários. Usando conexões de soquete binário, você pode gravar código que interage com vários protocolos de Internet diferentes, como POP3, SMTP, IMAP e NNTP. Essa interação, por sua vez, permite que seus aplicativos se conectem a servidores de email e de notícias. O Flash Player pode fazer interface com um servidor usando o protocolo binário desse servidor diretamente. Alguns servidores usam a ordem de bytes big-endian, e outros utilizam a ordem de bytes little-endian. A maioria dos servidores na Internet usa a ordem de bytes big-endian porque a “ordem de bytes da rede” é big-endian. A ordem de bytes little-endian é popular porque é a usada pela arquitetura Intel® x86. Você deve usar a ordem de bytes endian compatível com a ordem de bytes do servidor que está enviando ou recebendo dados. Todas as operações executadas pelas interfaces IDataInput e IDataOutput, e as classes que implementam essas interfaces (ByteArray, Socket e URLStream), por padrão, são codificadas no formato big-endian, isto é, com o byte mais significativo primeiro. Esta ordem padrão de bytes foi escolhida para corresponder à ordem de bytes de rede oficial e do Java. Para alterar se a ordem de bytes big-endian ou a little-endian é usada, você pode definir a propriedade endian como Endian.BIG_ENDIAN ou Endian.LITTLE_ENDIAN. ![]() Para obter mais informações, consulte: Soquetes de cliente seguros (AIR)Você pode usar a classe SecureSocket para conexão a servidores de soquete que usam o Secure Sockets Layer versão 4 (SSLv4) ou o Transport Layer Security versão 1 (TLSv1). Um soquete seguro oferece três benefícios: autenticação do servidor, integridade de dados e sigilo da mensagem. O tempo de execução do autentica um servidor usando o certificado do servidor e seu relacionamento com os certificados raiz ou intermediários da autoridade de certificação no repositório confiável do usuário. O tempo de execução utiliza os algoritmos de criptografia usados pelas implementações de protocolo SSL e TLS para proporcionar integridade de dados e confidencialidade das mensagens. Quando você se conecta a um servidor através do objeto SecureSocket, o tempo de execução verifica o certificado do servidor utilizando o repositório confiável de certificados. No Windows e Mac, o sistema operacional fornece o armazenamento de confiança. No Linux, o tempo de execução do fornece seu próprio repositório confiável. Se o certificado do servidor não for válido nem confiável, o tempo de execução gerará um evento ioError. Você pode verificar a propriedade serverCertificateStatus do objeto SecureSocket para saber por que a verificação falhou. Não há nenhuma previsão para comunicação com um servidor que não possua um certificado válido e confiável. A classe CertificateStatus define as constantes alfanuméricas que representam os possíveis resultados da verificação:
A comunicação com um objeto SecureSocket exige que o servidor use um protocolo seguro e tenha um certificado válido e confiável. Em outros aspectos, usar o objeto SecureSocket é igual a usar um objeto Socket. O objeto SecureSocket não pode ser usado em todas as plataformas. Use a propriedade isSupported da classe SecureSocket para testar se o tempo de execução permite o uso do objeto SecureSocket no computador cliente atual. Para obter mais informações, consulte: Exemplo de soquete TCP: construção de um cliente TelnetO exemplo de Telnet demonstra técnicas de conexão com um servidor remoto e transmissão de dados usando a classe Socket. O exemplo demonstra as seguintes técnicas:
Para obter os arquivos do aplicativo deste exemplo, consulte www.adobe.com/go/learn_programmingAS3samples_flash_br. Os arquivos do aplicativo Telnet podem ser encontrados na pasta Amostras/Telnet. O aplicativo consiste nos seguintes arquivos:
Visão geral do aplicativo de soquete TelnetO arquivo TelnetSocket.mxml principal é responsável por criar a interface do usuário (UI) para o aplicativo inteiro. Além da UI, esse arquivo também define dois métodos, login() e sendCommand(), para conectar o usuário ao servidor especificado. O código a seguir lista o ActionScript no arquivo principal do aplicativo: import com.example.programmingas3.socket.Telnet; private var telnetClient:Telnet; private function connect():void { telnetClient = new Telnet(serverName.text, int(portNumber.text), output); console.title = "Connecting to " + serverName.text + ":" + portNumber.text; console.enabled = true; } private function sendCommand():void { var ba:ByteArray = new ByteArray(); ba.writeMultiByte(command.text + "\n", "UTF-8"); telnetClient.writeBytesToSocket(ba); command.text = ""; } A primeira linha de código importa a classe Telnet do pacote com.example.programmingas.socket personalizado. A segunda linha de código declara uma instância da classe Telnet, telnetClient, que é inicializada posteriormente pelo método connect(). Em seguida, o método connect() é declarado e inicializa a variável telnetClient declarada anteriormente. Esse método transmite o nome do servidor telnet especificado pelo usuário, a porta do servidor telnet e uma referência a um componente TextArea na lista de exibição que é usada para exibir as respostas de texto do servidor de soquete. As duas linhas finais do método connect() definem a propriedade title do Painel e ativam o componente Painel, o que permite que o usuário envie dados ao servidor remoto. O método final no arquivo principal do aplicativo, sendCommand(), é usado para enviar os comandos do usuário ao servidor remoto como um objeto ByteArray. Visão geral da classe TelnetA classe Telnet é responsável por conectar-se ao servidor Telnet remoto e enviar/receber dados. A classe Telnet declara as seguintes variáveis particulares: private var serverURL:String; private var portNumber:int; private var socket:Socket; private var ta:TextArea; private var state:int = 0; A primeira variável, serverURL, contém o endereço do servidor especificado pelo usuário ao qual conectar-se. A segunda variável, portNumber, é o número da porta na qual o servidor Telnet está em execução atualmente. Por padrão, o serviço Telnet é executado na porta 23. A terceira variável, socket, é uma instância de Socket que tentará conectar-se ao servidor definido pelas variáveis serverURL e portNumber. A quarta variável, ta, é uma referência a uma ocorrência do componente TextArea no Palco. Esse componente é usado para exibir respostas do servidor Telnet remoto ou qualquer mensagem de erro possível. A variável final, state, é um valor numérico usado para determinar quais opções são suportadas pelo cliente Telnet. Conforme visto anteriormente, a função do construtor da classe Telnet é chamada pelo método connect() no arquivo principal do aplicativo. O construtor Telnet utiliza três parâmetros: server, port e output. Os parâmetros server e port especificam o nome do servidor e o número da porta em que o servidor Telnet está executando. O parâmetro final, output, é uma referência a uma instância do componente TextArea no Palco onde a saída do servidor é exibida aos usuários. public function Telnet(server:String, port:int, output:TextArea) { serverURL = server; portNumber = port; ta = output; socket = new Socket(); socket.addEventListener(Event.CONNECT, connectHandler); socket.addEventListener(Event.CLOSE, closeHandler); socket.addEventListener(ErrorEvent.ERROR, errorHandler); socket.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler); socket.addEventListener(ProgressEvent.SOCKET_DATA, dataHandler); Security.loadPolicyFile("http://" + serverURL + "/crossdomain.xml"); try { msg("Trying to connect to " + serverURL + ":" + portNumber + "\n"); socket.connect(serverURL, portNumber); } catch (error:Error) { msg(error.message + "\n"); socket.close(); } } Gravação de dados em um soquetePara gravar dados em uma conexão de soquete, você pode chamar qualquer um dos métodos de gravação da classe Socket. Entre esses métodos de gravação estão os seguintes: writeBoolean(), writeByte(), writeBytes(), writeDouble() e outros. Então, esvazie os dados do buffer de saída usando o método flush(). No servidor Telnet, os dados são gravados na conexão de soquete usando o método writeBytes() que utiliza a matriz de bytes como um parâmetro e envia-a ao buffer de saída. O método writeBytesToSocket() é o seguinte: public function writeBytesToSocket(ba:ByteArray):void { socket.writeBytes(ba); socket.flush(); } Esse método é chamado pelo método sendCommand() do arquivo principal do aplicativo. Exibição de mensagens do servidor de soqueteSempre que uma mensagem é recebida do servidor de soquete, ou ocorre um evento, o método msg() personalizado é chamado. Esse método anexa uma sequência de caracteres ao TextArea no Palco e chama um método setScroll() personalizado, o que faz com que o componente TextArea role para a parte inferior. O método msg() é o seguinte: private function msg(value:String):void { ta.text += value; setScroll(); } Se você não rolou automaticamente o conteúdo do componente TextArea, os usuários precisarão arrastar manualmente as barras de rolagem na área de texto para ver a resposta mais recente do servidor. Rolagem de um componente TextAreaO método setScroll() contém uma única linha do ActionScript que rola o conteúdo do componente TextArea verticalmente de forma que o usuário possa ver a última linha do texto retornado. O seguinte snippet mostra o método setScroll(): public function setScroll():void { ta.verticalScrollPosition = ta.maxVerticalScrollPosition; } Esse método define a propriedade verticalScrollPosition, que é o número da linha superior de caracteres exibida atualmente, e define-a como o valor da propriedade maxVerticalScrollPosition. Soquetes XMLUm soquete XML permite que você crie uma conexão com um servidor remoto que permanece aberta até que ela seja expressamente fechada. Você pode trocar dados de string como, por exemplo, XML entre o servidor e o cliente. Um dos benefícios de utilizar um servidor de soquete XML é que o cliente não precisa solicitar dados expressamente. O servidor pode enviar dados sem aguardar por uma solicitação e enviar dados para cada cliente conectado. No Flash Player e em conteúdo Adobe AIR fora da área de segurança, as conexões XML requerem a presença de um arquivo de política de soquete no servidor destino. Para obter mais informações, consulte Controles de site (arquivos de política) eConexão a soquetes. A classe XMLSocket não pode encapsular em firewalls automaticamente porque, ao contrário do protocolo RTMP (Real-Time Messaging Protocol), ela não tem recurso de encapsulamento HTTP. Se você precisar usar o encapsulamento HTTP, considere o uso do Flash Remoting ou do Flash Media Server (que oferece suporte a RTMP). As restrições a seguir aplicam-se a como e onde o conteúdo do Flash Player ou de um aplicativo AIR fora da área de segurança do aplicativo pode utilizar um objeto XMLSocket para conectar-se ao servidor:
Nota: Pode ser desafiador configurar um servidor para comunicar-se com o objeto XMLSocket. Se o seu aplicativo não exigir interatividade em tempo real, use a classe URLLoader em vez da classe XMLSocket.
Você pode usar os métodos XMLSocket.connect() e XMLSocket.send() da classe XMLSocket para transferir XML para e de um servidor via conexão de soquete. O método XMLSocket.connect() estabelece uma conexão de soquete com uma porta de servidor Web. O método XMLSocket.send() analisa um objeto XML para o servidor especificado na conexão de soquete. Ao chamar o método XMLSocket.connect(), o aplicativo abre uma conexão TCP/IP com o servidor de mantém a conexão aberta até que uma das condições a seguir ocorra:
Conexão a um servidor com a classe XMLSocketPara criar uma conexão de soquete, é necessário criar uma aplicativo server side Flash Player ou AIR para aguardar pela solicitação de conexão do soquete e enviar a resposta para o aplicativo Flash Player ou AIR. Este tipo de aplicativo server side pode ser escrito em AIR ou em outra linguagem de programação como, por exemplo Java, Python ou Perl. Para utilizar a classe XMLSocket, o serviddor deve executar uma daemon que entenda o protocolo simples utilizado pela classe XMLSocket:
Criação e conexão a um servidor de soquete XML JavaO código a seguir demonstra um servidor XMLSocket simples criado em Java que aceita conexões de entrada e exibe as mensagens recebidas na janela do prompt de comando. Por padrão, um novo servidor é criado na porta 8080 da máquina local, embora você possa especificar um número de porta diferente quando iniciar o servidor a partir da linha de comando. Crie um novo documento de texto e adicione o seguinte código: import java.io.*; import java.net.*; class SimpleServer { private static SimpleServer server; ServerSocket socket; Socket incoming; BufferedReader readerIn; PrintStream printOut; public static void main(String[] args) { int port = 8080; try { port = Integer.parseInt(args[0]); } catch (ArrayIndexOutOfBoundsException e) { // Catch exception and keep going. } server = new SimpleServer(port); } private SimpleServer(int port) { System.out.println(">> Starting SimpleServer"); try { socket = new ServerSocket(port); incoming = socket.accept(); readerIn = new BufferedReader(new InputStreamReader(incoming.getInputStream())); printOut = new PrintStream(incoming.getOutputStream()); printOut.println("Enter EXIT to exit.\r"); out("Enter EXIT to exit.\r"); boolean done = false; while (!done) { String str = readerIn.readLine(); if (str == null) { done = true; } else { out("Echo: " + str + "\r"); if(str.trim().equals("EXIT")) { done = true; } } incoming.close(); } } catch (Exception e) { System.out.println(e); } } private void out(String str) { printOut.println(str); System.out.println(str); } } Salve o documento no disco rígido como SimpleServer.java e o compile usando um compilador Java, que cria um arquivo de classe Java chamado SimpleServer.class. Você pode iniciar o servidor XMLSocket abrindo um prompt de comando e digitando java SimpleServer. O arquivo SimpleServer.class pode ser colocado em qualquer lugar do computador local ou da rede; não é necessário colocá-lo no diretório raiz do servidor Web. ![]() Para se conectar ao XMLSocket do aplicativo , é necessário criar uma nova ocorrência da classe XMLSocket, e chamar o método XMLSocket.connect() ao transmitir um nome do host e um número de porta, da seguinte maneira: var xmlsock:XMLSocket = new XMLSocket(); xmlsock.connect("127.0.0.1", 8080); Sempre que você receber dados do servidor, o evento data (flash.events.DataEvent.DATA) é despachado: xmlsock.addEventListener(DataEvent.DATA, onData); private function onData(event:DataEvent):void { trace("[" + event.type + "] " + event.data); } Para enviar dados ao servidor XMLSocket, use o método XMLSocket.send() e transmita um objeto ou string XML. O Flash Player converte o parâmetro fornecido em um objeto String e envia o conteúdo ao servidor XMLSocket seguido de um byte zero (0): xmlsock.send(xmlFormattedData); O método XMLSocket.send() não retorna um valor que indica se os dados foram transmitidos com êxito. Se houve um erro durante a tentativa de enviar dados, é gerado um erro IOError. ![]() Para obter mais informações, consulte XMLSocket. Soquetes de servidorUse a classe ServerSocket para permitir que outros processos se conectem ao seu aplicativo usando um soquete do Protocolo de Controle de Transporte (TCP). O processo em conexão pode estar sendo executado no computador local ou em outro computador conectado à rede. Quando um objeto ServerSocket recebe uma solicitação de conexão, ele gera um evento connect. O objeto ServerSocketConnectEvent gerado com o evento contém um objeto Socket. Você pode usar esse objeto Socket em comunicações subsequentes com o outro processo. Para ouvir conexões de soquete recebidas:
O objeto ServerSocket continua a escutar novas conexões até que você chame o método close(). O exemplo de código a seguir ilustra como criar um aplicativo de servidor de soquete. O exemplo ouve conexões que chegam à porta 8087. Quando uma conexão for recebida, o exemplo envia uma mensagem (a sequência de caracteres “Conectado”) para o soquete do cliente. Daí em diante, o servidor "rebate" todas as mensagens para o cliente. package { import flash.display.Sprite; import flash.events.Event; import flash.events.IOErrorEvent; import flash.events.ProgressEvent; import flash.events.ServerSocketConnectEvent; import flash.net.ServerSocket; import flash.net.Socket; public class ServerSocketExample extends Sprite { private var serverSocket:ServerSocket; private var clientSockets:Array = new Array(); public function ServerSocketExample() { try { // Create the server socket serverSocket = new ServerSocket(); // Add the event listener serverSocket.addEventListener( Event.CONNECT, connectHandler ); serverSocket.addEventListener( Event.CLOSE, onClose ); // Bind to local port 8087 serverSocket.bind( 8087, "127.0.0.1" ); // Listen for connections serverSocket.listen(); trace( "Listening on " + serverSocket.localPort ); } catch(e:SecurityError) { trace(e); } } public function connectHandler(event:ServerSocketConnectEvent):void { //The socket is provided by the event object var socket:Socket = event.socket as Socket; clientSockets.push( socket ); socket.addEventListener( ProgressEvent.SOCKET_DATA, socketDataHandler); socket.addEventListener( Event.CLOSE, onClientClose ); socket.addEventListener( IOErrorEvent.IO_ERROR, onIOError ); //Send a connect message socket.writeUTFBytes("Connected."); socket.flush(); trace( "Sending connect message" ); } public function socketDataHandler(event:ProgressEvent):void { var socket:Socket = event.target as Socket //Read the message from the socket var message:String = socket.readUTFBytes( socket.bytesAvailable ); trace( "Received: " + message); // Echo the received message back to the sender message = "Echo -- " + message; socket.writeUTFBytes( message ); socket.flush(); trace( "Sending: " + message ); } private function onClientClose( event:Event ):void { trace( "Connection to client closed." ); //Should also remove from clientSockets array... } private function onIOError( errorEvent:IOErrorEvent ):void { trace( "IOError: " + errorEvent.text ); } private function onClose( event:Event ):void { trace( "Server socket closed by OS." ); } }} Para obter mais informações, consulte: Soquetes UDP (AIR)O Protocolo Universal de Datagramas (UDP) é uma forma de troca de mensagens através de uma conexão de rede sem estado (stateless). O UDP não garante que as mensagens serão entregues na ordem nem que elas serão realmente entregues. Com o UDP, o código de rede do sistema operacional normalmente gasta menos tempo organizando, rastreando e confirmando as mensagens. Portanto, as mensagens de UDP normalmente chegam ao aplicativo de destino com um atraso menor do que as mensagens de TCP. A comunicação por soquete do UDP é útil quando existe a necessidade de enviar informações em tempo real, tais como atualizações de posições em um jogo ou pacotes de som em um aplicativo de bate-papo por voz. Nesses aplicativos, é aceitável alguma perda de dados, e uma baixa latência de transmissão é mais importante que a garantia de chegada. Para praticamente todas as outras finalidades, os soquetes TCP são uma opção mais adequada. Seu aplicativo AIR pode enviar e receber mensagens UDP com as classes DatagramSocket e DatagramSocketDataEvent. Para enviar ou receber uma mensagem UDP:
O exemplo de código a seguir ilustra como um aplicativo pode enviar e receber mensagens UDP. O exemplo envia uma única mensagem contendo a sequência de caracteres, “Olá.” ao computador de destino. Ele também rastreia o conteúdo de todas as mensagens recebidas. package { import flash.display.Sprite; import flash.events.DatagramSocketDataEvent; import flash.events.Event; import flash.net.DatagramSocket; import flash.utils.ByteArray; public class DatagramSocketExample extends Sprite { private var datagramSocket:DatagramSocket; //The IP and port for this computer private var localIP:String = "192.168.0.1"; private var localPort:int = 55555; //The IP and port for the target computer private var targetIP:String = "192.168.0.2"; private var targetPort:int = 55555; public function DatagramSocketExample() { //Create the socket datagramSocket = new DatagramSocket(); datagramSocket.addEventListener( DatagramSocketDataEvent.DATA, dataReceived ); //Bind the socket to the local network interface and port datagramSocket.bind( localPort, localIP ); //Listen for incoming datagrams datagramSocket.receive(); //Create a message in a ByteArray var data:ByteArray = new ByteArray(); data.writeUTFBytes("Hello."); //Send the datagram message datagramSocket.send( data, 0, 0, targetIP, targetPort); } private function dataReceived( event:DatagramSocketDataEvent ):void { //Read the data from the datagram trace("Received from " + event.srcAddress + ":" + event.srcPort + "> " + event.data.readUTFBytes( event.data.bytesAvailable ) ); } }} Não se esqueça dos seguintes aspectos quando usar soquetes UDP:
Para obter mais informações, consulte: Endereços IPv6O Flash Player 9.0.115.0 e suas versões posteriores oferecem suporte a IPv6 (Internet Protocol versão 6). O IPv6 é uma versão do Internet Protocol que oferece suporte a endereços de 128 bits (um aprimoramento do protocolo IPv4 anterior, que oferece suporte a endereços de 32 bits). Talvez seja necessário ativar o IPv6 nas suas interfaces de rede. Para obter mais informações, consulte a Ajuda do sistema operacional que está hospedando os dados. Se o IPv6 for suportado no sistema de host, será possível especificar endereços literais IPv6 numéricos em URLs, contidos entre parênteses ([]), como apresentado seguir: [2001:db8:ccc3:ffff:0:444d:555e:666f] O Flash Player retorna valores IPv6 literais, de acordo com as regras a seguir:
Os valores IPv6 retornados pelo Flash Player têm as seguintes exceções:
|
![]() |