FLEX IO 之XMLSocket

一门好的语言需要良好的支持IO操作, Java有了Socket才有了JDBC, Servlet, Tomcat and etc.

先看下FLEX的XMLSocket.

 

XMLSocket提供的接口比较简单, 文档还有简单的例子, 跟Java区别写法比较大的就是它异步的回调.

 

FLASH客户端代码:

  1. 一门好的语言需要良好的支持IO操作, Java有了Socket才有了JDBC, Servlet, Tomcat and etc.
  2. 先看下FLEX的XMLSocket.
  3. XMLSocket提供的接口比较简单, 文档还有简单的例子, 跟Java区别写法比较大的就是它异步的回调.
  4. <?xml version="1.0" encoding="utf-8"?>
  5. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="800" height="600" creationComplete="initApp()">
  6. <mx:Script><![CDATA[
  7.     import mx.controls.Alert;
  8. private var sock:XMLSocket = null;
  9. //Initial the GUI 
  10. private function initApp():void {
  11. }
  12. //Click logon 
  13. private function connectServer(event:MouseEvent):void {
  14.     if (this.sock != null)
  15.         return;
  16.     this.sock = new XMLSocket();
  17.     //Refer to XMLSocket document, follow the sample here 
  18.     this.configureListeners(this.sock);
  19.     this.sock.connect("localhost"8080);
  20.     this.sendButton.enabled = true;
  21. }
  22.         public function send(data:Object):void {
  23.             this.sock.send(data);
  24.         }
  25.         private function configureListeners(dispatcher:IEventDispatcher):void {
  26.             dispatcher.addEventListener(Event.CLOSE, closeHandler);
  27.             dispatcher.addEventListener(Event.CONNECT, connectHandler);
  28.             dispatcher.addEventListener(DataEvent.DATA, dataHandler);
  29.             dispatcher.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
  30.             dispatcher.addEventListener(ProgressEvent.PROGRESS, progressHandler);
  31.             dispatcher.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
  32.         }
  33.         private function closeHandler(event:Event):void {
  34.             trace("closeHandler: " + event);
  35.             this.appendLine("CLose event socket");
  36.         }
  37.         private function connectHandler(event:Event):void {
  38.             trace("connectHandler: " + event);
  39.             this.appendLine("Send: connect to server sucessfully." + event.target.toLocaleString());
  40.             
  41.         }
  42.         private function appendLine(mesg:String):void {
  43.             //The /0 will be added automatically like C 
  44.             this.messageArea.text += (mesg);
  45.         }
  46.         private function dataHandler(event:DataEvent):void {
  47.             trace("dataHandler: " + event);
  48.             this.appendLine("Server Response:" + event.data);
  49.             //this.messageArea.text += ("Server Response:" + event.target.toLocaleString() + "/r/n"); 
  50.         }
  51.         private function ioErrorHandler(event:IOErrorEvent):void {
  52.             trace("ioErrorHandler: " + event);
  53.             this.appendLine("Oops, ioError");
  54.         }
  55.         private function progressHandler(event:ProgressEvent):void {
  56.             trace("progressHandler loaded:" + event.bytesLoaded + " total: " + event.bytesTotal);
  57.         }
  58.         private function securityErrorHandler(event:SecurityErrorEvent):void {
  59.             trace("securityErrorHandler: " + event);
  60.             this.appendLine("Oops, encounter security error:" + event.text);
  61.         }
  62.         
  63.         private function sendMessage(event:MouseEvent):void {
  64.             var message:String = this.messageField.text;
  65.             //message = "<message>" + message + "</message>/r/n"; 
  66.             message = message + "/r/n";  
  67.             if (message != null && message.length > 0) {
  68.                 this.send(message);
  69.                 //this.messageArea.text += ("Send:" + message + "/r/n"); 
  70.                 this.appendLine("Send:" + message );
  71.             }
  72.         }
  73. ]]>
  74. </mx:Script>
  75.             
  76.     <mx:TextArea x="10" y="10" width="780" height="386" id="messageArea"/>
  77.     <mx:TextInput x="10" y="416" width="536" height="31" id="messageField"/>
  78.     <mx:Button x="577" y="416" label="Send" height="31" width="69" id="sendButton" enabled="false" click="sendMessage(event)"/>
  79.     <mx:Button x="669" y="416" label="Logon" height="31" id="logonButton" click="connectServer(event)"/>
  80.     
  81. </mx:Application>

JAVA服务器:

 

  1. /*
  2.  * testflex.CellPhoneLocator.java       2008-12-23
  3.  */
  4. package testflex;
  5. import java.io.BufferedReader;
  6. import java.io.IOException;
  7. import java.io.InputStream;
  8. import java.io.InputStreamReader;
  9. import java.io.PrintWriter;
  10. import java.io.UnsupportedEncodingException;
  11. import java.net.InetAddress;
  12. import java.net.ServerSocket;
  13. import java.net.Socket;
  14. import java.util.Date;
  15. import java.util.HashMap;
  16. import java.util.Map;
  17. import java.util.StringTokenizer;
  18. /**
  19.  * The demo provided to test the flash XMLSocket
  20.  * @author zealvampire
  21.  * @version 1.0  2008-12-23
  22.  */
  23. public class CellPhoneLocator {
  24.     
  25.     /** The listening port of server. */
  26.     private int serverPort = 8080;
  27.     private int backlog = 50;
  28.     private InetAddress bindAddress = null;
  29.     private Map<String,String> questions = new HashMap<String,String>(5);
  30.     private boolean toStopServer = false;
  31.     
  32.     //Open 843 to handle the policy request.
  33.     private PolicyService policyService = null;
  34.     /** The server socket */
  35.     private ServerSocket serverSocket = null;
  36.     
  37.     
  38.     
  39.     public CellPhoneLocator() {
  40.         questions.put("130""130's from chinaunicom");
  41.         questions.put("131""131's from chinaunicom");
  42.         questions.put("133""133's from Chinatelecom");
  43.         questions.put("135""135's from China Mobile");
  44.         questions.put("138""138's from China Mobile");
  45.     }
  46.     
  47.     private String locateNumber(String phoneNum)  {
  48.         String location = this.questions.get(phoneNum);
  49.         return location==null ? (phoneNum + "'s Unknown") : location;
  50.     }
  51.     
  52.     
  53.     private class FlexStringReader extends InputStreamReader {
  54.         
  55.         private StringBuffer buf = new StringBuffer();
  56.         public FlexStringReader(InputStream in) {
  57.             super(in);
  58.         }
  59.         public FlexStringReader(InputStream in, String charsetName) throws UnsupportedEncodingException {
  60.             super(in, charsetName);
  61.         }
  62.         //Make sure it works.
  63.         public String readLine() throws IOException {
  64.             int oneChar = 0;
  65.             buf.setLength(0);
  66.             while ((oneChar = this.read()) != -1) {
  67.                 if (oneChar == '/0')
  68.                     break;
  69.                 buf.append((char) oneChar);
  70.             }
  71.             return buf.toString();
  72.         }
  73.         
  74.     }
  75.     
  76.     private class RequestHanlder implements Runnable {
  77.         private Socket sock = null;
  78.         public RequestHanlder(Socket pSock) {
  79.             this.sock = pSock;
  80.         }
  81.         private String command = "";
  82.         private String parameter = "";
  83.         public void run() {
  84.             FlexStringReader reader = null;
  85.             PrintWriter pw = null;
  86.             String line = null;
  87.             try {
  88.                 System.out.println("Client:" + this.sock);
  89.                 InputStream in = this.sock.getInputStream();
  90.                 reader = new FlexStringReader(in, "UTF-8");
  91.                 pw = new PrintWriter(this.sock.getOutputStream());
  92.                 String policyRequest = reader.readLine();//new String(headers);
  93.                 //FLash client will open two ports, one to retrieve the policy.
  94.                 //Another to normal communicate to server. 
  95.                 if (policyRequest.startsWith("<policy-file-request/>")) {
  96.                     pw.write("<?xml version=/"1.0/"?><cross-domain-policy><site-control permitted-cross-domain-policies=/"all/"/><allow-access-from domain=/"*/" to-ports=/"*/" /></cross-domain-policy>/0");
  97.                     pw.flush();
  98.                     System.out.println("Policy's sent by current listening port:" + serverPort);
  99.                     Thread.sleep(10000);
  100.                     throw new IOException("A dirty return, never follow it dude.");
  101.                 }
  102.                 else {
  103.                     pw.write("Hi " + this.sock + ",at your service, send me the cell phone please./0");
  104.                 }
  105.                 pw.flush();
  106.                 while ((line = reader.readLine()).length() > 0) {
  107.                     this.parseRequest(line);
  108.                     if ("where".equalsIgnoreCase(command)) {
  109.                         pw.write(locateNumber(this.parameter)+ '/0');
  110.                         pw.flush();
  111.                     }
  112.                     else if ("quit".equalsIgnoreCase(command) || "exit".equalsIgnoreCase(command)) {
  113.                         break;
  114.                     }
  115.                     else {
  116.                         pw.write("Oops, unknown command./0");
  117.                         pw.flush();
  118.                     }
  119.                 }
  120.             }
  121.             catch (IOException e) {
  122.                 e.printStackTrace();
  123.             } catch (InterruptedException e) {
  124.                 e.printStackTrace();
  125.             }
  126.             finally {
  127.                 //FIXME, try to close the I/O stream
  128.                 try {
  129.                     sock.close();
  130.                 } catch (IOException e) {
  131.                     e.printStackTrace();
  132.                 }
  133.             }
  134.             
  135.         }
  136.         private void parseRequest(String line) {
  137.             command = "";
  138.             parameter = "";
  139.             StringTokenizer tokens = new StringTokenizer(line, " /t/n/r/f/0"false);
  140.             int count = tokens.countTokens();
  141.             if (count  > 0) {
  142.                 this.command = tokens.nextToken();
  143.                 if (count > 1)
  144.                     this.parameter = tokens.nextToken();
  145.             }
  146.             System.out.println("Command=" + this.command + "/tParameter=" + this.parameter);
  147.         }
  148.         
  149.     }
  150.     
  151.     /**
  152.      * Start the server first.
  153.      * @throws IOException
  154.      */
  155.     public void startServer() throws IOException {
  156.         this.serverSocket = new ServerSocket(serverPort, backlog, bindAddress);
  157.         System.out.println(new Date() + ": Starting server.");
  158.         
  159.         //The policy swith
  160.         this.policyService = new PolicyService();
  161.         this.policyService.start();
  162.     }
  163.     
  164.     private class PolicyService extends Thread {
  165.         private ServerSocket policySock = null;
  166.         public void run() {
  167.             try {
  168.                 this.policySock = new ServerSocket(843);
  169.                 System.out.println(new Date() + ":The policy server is running on 843......");
  170.                 Socket sock = null;
  171.                 String request = null;
  172.                 FlexStringReader br = null;
  173.                 PrintWriter pw = null;
  174.                 //FIXME, create another thread to handle the request.
  175.                 while ((sock = this.policySock.accept()) != null) {
  176.                     br = new FlexStringReader(sock.getInputStream());
  177.                     pw = new PrintWriter(sock.getOutputStream());
  178.                     System.out.println("Policy server:client socket=" + sock);
  179.                     request = br.readLine();
  180.                     System.out.println("Policy service: request=" + request);
  181.                     if (request.startsWith("<policy-file-request/>")) {
  182.                         pw.write("<?xml version=/"1.0/"?><cross-domain-policy><site-control permitted-cross-domain-policies=/"all/"/><allow-access-from domain=/"*/" to-ports=/"*/" /></cross-domain-policy>/0");
  183.                         pw.flush();
  184.                         System.out.println("Policy service:Policy file's sent......");
  185.                         //Wait until the xml's pushed to client.
  186.                         Thread.sleep(10000);
  187.                     }
  188.                     //FIXME, not a good way the release resources. 
  189.                     System.out.println("Policy service: close the client socket.");
  190.                     br.close();
  191.                     pw.close();
  192.                     sock.close();
  193.                 }
  194.             } catch (IOException e) {
  195.                 e.printStackTrace();
  196.             } catch (InterruptedException e) {
  197.                 e.printStackTrace();
  198.             }  finally {
  199.                 //FIXME, refactor it ..
  200.                 if (this.policySock != null) {
  201.                     try {
  202.                         this.policySock.close();
  203.                     } catch (IOException e) {
  204.                         e.printStackTrace();
  205.                     }
  206.                 }
  207.             }
  208.         }
  209.     }
  210.     
  211.     /**
  212.      * Service's running
  213.      * @throws IOException
  214.      */
  215.     public void service() throws IOException {
  216.         Socket clientSock = null;
  217.         Thread handler = null;
  218.         while (!this.toStopServer && (clientSock = this.serverSocket.accept()) != null) {
  219.             //FIXME, only a demo, try to control the threads using producer/consumer,threadpool in your project.
  220.             handler = new Thread(new RequestHanlder(clientSock));
  221.             handler.start();
  222.         }
  223.         this.releaseResource();
  224.         
  225.     }
  226.     public void releaseResource() {
  227.         if (this.serverSocket != null)
  228.             try {
  229.                 this.serverSocket.close();
  230.                 this.serverSocket = null;
  231.             } catch (IOException e) {
  232.                 // TODO Auto-generated catch block
  233.                 e.printStackTrace();
  234.             }
  235.     }
  236.     
  237.     
  238.     
  239.     
  240.     /**
  241.      * @param args
  242.      */
  243.     public static void main(String[] args) {
  244.         CellPhoneLocator server = new CellPhoneLocator();
  245.         try {
  246.             server.startServer();
  247.             server.service();
  248.         } catch (IOException e) {
  249.             e.printStackTrace();
  250.             server.releaseResource();
  251.         }
  252.         
  253.     }
  254.     /**
  255.      * @return the serverPort
  256.      */
  257.     public int getServerPort() {
  258.         return serverPort;
  259.     }
  260.     /**
  261.      * @param serverPort the serverPort to set
  262.      */
  263.     public void setServerPort(int serverPort) {
  264.         this.serverPort = serverPort;
  265.     }
  266. }

麻烦的只是权限, 因为flash player只相信一个原则, SWF从哪里来, 它就相信哪个域; 也就是说SWF本地运行还有从网络下载到浏览器它的采访权限是完全不一样的, SANDBOX沙漏这个限制就好像java applet一样. 我们需要设置好policy.

 

1. 在本地Flash player运行, I mean 直接点击生成的SWF

不需要设置, XMLSocket可以直接发送接受服务器的信息.  不过我这里用的都是localhost, 不知道使用外部IP会如何..不确定.

 

2. SWF放在web 服务器下, 使用浏览器采访

(1)默认先连XMLSocket目标服务器的843端口, 发送<policy-file-request/>/0 类似这样的信息.

我们返回"<?xml version=/"1.0/"?><cross-domain-policy><site-control permitted-cross-domain-policies=/"all/"/><allow-access-from domain=/"*/" to-ports=/"*/" /></cross-domain-policy>/0"

 

(2) 如1失败, 则查看AS中是否

Security.loadPolicyFile( "xmlsocket://host:port" )  有则尝试加载crossdomain.xml

(3)2失败则只能链XMLSocket的目标端口了. 还失败就不可能建立连接了.

 

3.需要注意的是XMLSocket未必一定要发送XML, 你也可以直接发送String, 但是flex里面的string发送过去是以/0结束的.

后台需要额外处理一下/0; 返回到flash的字符串也必须使用/0才能在在客户端接收到. 冇办法, 每个语言都有自己的规则.

        private function dataHandler(event:DataEvent):void {
            trace("dataHandler: " + event);
            this.appendLine("Server Response:" + event.data);
            //this.messageArea.text += ("Server Response:" + event.target.toLocaleString() + "/r/n");
        }

 

 

 

之后会继续测试一下Flex 的binary socket和其他IO

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值