原创  关于socket跨域访问时请求策略文件问题 收藏

经常有人会问起 action script的socket跨域访问问题,闲来无事就总结一下。
跨域:
当你的flash应用程序部署在域A:www.a.com,而socket服务端部署在其他的域B:www.b.com时,就会产生跨越访问的问题,也就是常说的安全沙箱限制。
跨域访问请求:
当flash需要进行跨越访问时,flash底层会
1、先向目标服务器的843端口请求有效的安全策略文件,如果过请求得不到相应或者请求到的策略文件无效,将
2、会想目标服务器的目标端口(就是你需要连接的端口)请求策略文件,如果得不到有效策略文件,请求将被中止,并抛出安全限制异常。
跨域访问解决方案:
首先,我们需要知道flash是怎么请求安全策略的。随便找个封包截获器就可以截获到请求策略的消息,flash是通过发送消息“<policy-file-request/>”请求策略文件。
于是,要使得请求端能得到策略文件,在收到这个消息的时候,就应该将策略配置文件返回给请求端。以下是几种可以参考的方法。
1、在服务器的843端口监听策略文件请求。
2、在逻辑服务器(需要连接的服务器)端口处理该消息,并返回策略配置。
3、单独开辟一个端口负责策略文件请求,当然这需要 flash在发起连接请求前先主动通过这个端口请求策略。
怎么主动请求策略文件,可以参考官方帮助文档,比较详细。
至于服务的如何返回,下面给出一段java代码,是openfire服务器(java实现的jabber服务器)的处理flash安全策略的实现:
  1. /**
  2.  * $RCSfile: $
  3.  * $Revision: $
  4.  * $Date: $
  5.  *
  6.  * Copyright (C) 2008 Jive Software. All rights reserved.
  7.  *
  8.  * This software is published under the terms of the GNU Public License (GPL),
  9.  * a copy of which is included in this distribution, or a commercial license
  10.  * agreement with Jive.
  11.  */
  12. package org.jivesoftware.openfire;
  13. import org.jivesoftware.openfire.container.BasicModule;
  14. import org.jivesoftware.util.JiveGlobals;
  15. import org.jivesoftware.util.Log;
  16. import java.io.IOException;
  17. import java.io.PrintWriter;
  18. import java.net.InetAddress;
  19. import java.net.ServerSocket;
  20. import java.net.Socket;
  21. public class FlashCrossDomainHandler extends BasicModule {
  22.     private ServerSocket serverSocket;
  23.     public static String CROSS_DOMAIN_TEXT = "<?xml version=\"1.0\"?>" +
  24.             "<!DOCTYPE cross-domain-policy SYSTEM \"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd\">" +
  25.             "<cross-domain-policy>" +
  26.             "<allow-access-from domain=\"*\" to-ports=\"";
  27.     public static String CROSS_DOMAIN_END_TEXT = "\" /></cross-domain-policy>";
  28.     public FlashCrossDomainHandler() {
  29.         super("Flash CrossDomain Handler");
  30.     }
  31.     public void start() {
  32.         Thread thread = new Thread(new Runnable() {
  33.             public void run() {
  34.                 try {
  35.                     startServer();
  36.                 }
  37.                 catch (Exception e) {
  38.                     Log.error(e);
  39.                 }
  40.             }
  41.         }, "Flash Cross Domain");
  42.         thread.start();
  43.     }
  44.     public void stop() {
  45.         try {
  46.             if (serverSocket != null) {
  47.                 serverSocket.close();
  48.             }
  49.         }
  50.         catch (IOException e) {
  51.             Log.error(e);
  52.         }
  53.     }
  54.     public int getPort() {
  55.         return serverSocket != null ? serverSocket.getLocalPort() : 0;
  56.     }
  57.     private void startServer() throws Exception {
  58.         try {
  59.             // Listen on a specific network interface if it has been set.
  60.             String interfaceName = JiveGlobals.getXMLProperty("network.interface");
  61.             InetAddress bindInterface = null;
  62.             int port = 5229;
  63.             if (interfaceName != null) {
  64.                 if (interfaceName.trim().length() > 0) {
  65.                     bindInterface = InetAddress.getByName(interfaceName);
  66.                 }
  67.             }
  68.             serverSocket = new ServerSocket(port, -1, bindInterface);
  69.             Log.debug("Flash cross domain is listening on " + interfaceName + " on port " + port);
  70.         }
  71.         catch (IOException e) {
  72.             Log.error("Could not listen on port: 5229.", e);
  73.             return;
  74.         }
  75.         while (true) {
  76.             Socket clientSocket;
  77.             try {
  78.                 clientSocket = serverSocket.accept();
  79.                 // Validate that we have a license
  80.                 PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
  81.                 out.println(CROSS_DOMAIN_TEXT +
  82.                         XMPPServer.getInstance().getConnectionManager().getClientListenerPort() +
  83.                         CROSS_DOMAIN_END_TEXT);
  84.                 out.println("\n");
  85.                 out.flush();
  86.                 out.close();
  87.             }
  88.             catch (IOException e) {
  89.                 if (XMPPServer.getInstance().isShuttingDown()) {
  90.                     break;
  91.                 }
  92.                 Log.error(e);
  93.             }
  94.         }
  95.     }
  96. }

上面的代码中已经将策略配置定义在变量CROSS_DOMAIN_TEXT中,并允许了所有域和对所有端口的请求,具体如何配置域限制和端口限制,参见flash帮助文档。

发表于 @ 2008年08月28日 14:57:00 | 评论( loading... ) | 编辑| 举报| 收藏

旧一篇:flash MovieClip色彩调节(AS2实现) | 新一篇:CustomValidator不工作问题

  • 发表评论
  • 评论内容:
  •  
Copyright © lulustray
Powered by CSDN Blog