在项目中有需要兼容IE客户端websocket使用的需求,百度了一番发现目前很多都采用github上开源项目https://github.com/gimite/web-socket-js的实现。

项目配置:

服务器jetty9.2

客户端IE8

websocket连接地址:ws://localhost:8082

按照开源项目的配置出现如下错误

 

 

这个问题其实在websocket-js的readme中有说明,因为flash的安全策略问题,需要向后台请求安全策略文件,如果服务器对安全策略请求没有响应,那么websocket连接会被关闭。开源项目并没有实现jetty服务器的843端口上的安全策略响应,因此需要自己实现。

建立websocket时,web-socket-js向服务器843端口发送安全策略请求,文件如下

<policy-file-request/> 

服务器应该在判断收到请求后返回安全策略文件,文件内容如下:

<?xml version="1.0"?>

<cross-domain-policy>

    <site-control permitted-cross-domain-policies="all"/>

    <allow-access-from domain="*" to-ports="8082" />

</cross-domain-policy>

将8082端口设置为任何域都可访问,即允许flash端访问8082端口

发送安全策略文件的代码

package tt;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 为了兼容IE8浏览器,WebSocket采用Adobe Flash来实现,而Flash由于安全策略问题,会向TCP:843端口发送请求文件,服务器应该返回安全策略文件给客户端。
 */
public class WebSocketPolicyListener implements Runnable {
    private ServerSocket server;

    public WebSocketPolicyListener(){
        try {
            server=new ServerSocket(843);
            System.out.println("Adobe Flash安全策略监听启动");
        } catch (IOException e) {
            System.err.println();
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        while(true){
            try {
                Socket s=server.accept();
                //获取安全策略请求文件
                BufferedInputStream bin=new BufferedInputStream(s.getInputStream());//打开文件流//
                //网络操作调用avaiable()方法时,可能数据并没有到达,这时需要等待数据变为可用
                int avaiable=0;
                //当有可用数据时,退出循环
                while(avaiable==0){
                    avaiable=bin.available();
                }
                byte[] buf=new byte[avaiable];
                int count=bin.read(buf);
                String request=new String(buf,0,count);
                System.out.println("安全策略文件请求:\n"+request);

                //如果是安全策略文件请求,将安全策略文件发给客户端
                if(request.indexOf("<policy-file-request/>")!=-1){
                    //获取文件路径,我放在src目录下
                    String path=WebSocketPolicyListener.class.getResource("/").getPath()+"websocket-policy.xml";
                    FileInputStream fin=new FileInputStream(path);
                    buf=new byte[1024];
                    StringBuilder sb=new StringBuilder();
                    while((count=fin.read(buf))>0){
                        s.getOutputStream().write(buf,0,count);
                        sb.append(new String(buf,0,count));
                    }
                    System.out.println("安全策略文件响应:\n"+sb.toString());
                    fin.close();//关闭文件流
                }

                s.close();//关闭Socket流
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }
}

 

 这里我对到843端口的请求都返回安全策略文件,有需求的大家可以做判断

将这个线程随WEB容器启动而启动监听即可。

 

 

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐