行业知识
SpringBoot之整合WebSocket服务并兼容IE8浏览器的方式
2026-10-30 13:46:17
来源:互联网转载
SpringBoot之整合WebSocket服务并兼容IE8浏览器的方式
文章目录
- SpringBoot之整合WebSocket服务并兼容IE8浏览器的方式
- 1. web-socket-js
- 1.下载web-socket-js
- 2. 配置
- 2. FlashSocket安全服务策略文件843端口配置
- 1. 配置方式1_xxx.xml配置方式
- 1. 编写flash843端口监听类
- 2. SpringBoot应用启时启动843监听程序配置
- 3. 配置flash通信协议的策略文件
- 2. 配置方式2_Java编码方式
- 1.编写监听843端口的服务类
- 2. 实现**ServletContextListener**监听接口并在实现方法中启动843端口监听类
- 3. 编写页面进行调试
- 4. 启动应���进行测试
- SpringBoot整合WebSocket过程请查看 SpringBoot之WebSocket服务搭建;
- 以下WebSocket兼容IE8浏览器的方式就是在 SpringBoot之WebSocket服务搭建基础上完成的。
1. web-socket-js
-
为了兼容IE8浏览器,WebSocket采用Adobe Flash来实现,而Flash由于安全策略问题,会向TCP:843端口发送请求文件,服务器应该返回安全策略文件给客户端;
() -
这里是使用开源项目web-socket-js对IE8中使用webSocket进行兼容适配与实现;
-
web-socket-js官网地址:https://github.com/gimite/web-socket-js
()
1.下载web-socket-js
从官网中下载并提取swfobject.js、web_socket.js、WebSocketMain.swf等三个文件
2. 配置
将上面三个文件放在SpringBoot静态资源目录下
- 在·src\main\resources\static目录下新建myjs文件夹,并将swfobject.js与web_socket.js`放在myjs中
- 将WebSocketMain.swf放在跟目录src\main\resources\下
2. FlashSocket安全服务策略文件843端口配置
1. 配置方式1_xxx.xml配置方式
此配置方式只需要两步:
- 编写一个flash安全服务策略文件监听843端口的监听器线程类;
- 在spring boot应用启动后,随即启动监听843端口的监听器线程;
- 配置flash通信协议的策略文件
1. 编写flash843端口监听类
兼容IE8方式1:将crossdomain.xml改名后放在跟目录下的方式
package org.yuan.mysoket;import java.io.BufferedInputStream;import java.io.FileInputStream;import java.io.IOException;import java.net.ServerSocket;import java.net.Socket;/** * 兼容IE8方式1:将crossdomain.xml改名后放在跟目录下的方式 * 为了兼容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) { System.out.println("线程run"); 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("") != -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(); } } }}2. SpringBoot应用启时启动843监听程序配置
实现CommandLineRunner接口,并在run方法中启动WebSocketPolicyListener
package org.yuan.config;import org.springframework.boot.CommandLineRunner;import org.springframework.stereotype.Component;import org.yuan.mysoket.WebSocketPolicyListener;@Componentpublic class InitConfig implements CommandLineRunner { @Override public void run(String... args) throws Exception { WebSocketPolicyListener webSocketPolicyListener = new WebSocketPolicyListener(); new Thread(webSocketPolicyListener).start(); }}3. 配置flash通信协议的策略文件
默认的策略文件名为crossdomain.xml;
-
这里我自己定义为ebsocket-policy.xml,并将此文件放在项目跟目录下;
-
如src\main\resources\websocket-policy.xml
websocket-policy.xml内容如下
2. 配置方式2_Java编码方式
1.编写监听843端口的服务类
SocketService.java类如下J
package org.yuan.config;import java.io.*;import java.net.ServerSocket;import java.net.Socket;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;/** * 兼容IE8方式2:将crossdomain.xml中的内容直接写入Java代码中 * 这个socket主要还是为了flash的socket */public class SocketService { private ServerSocket serverSocket = null; private static Object locker = new Object(); // 线程池 private static ExecutorService executorService = null; public synchronized void initSocketServer() { try { if (executorService == null) { executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 20); } else { return; } //启动843端口 serverSocket = new ServerSocket(843); Runnable runnable = new Server(); Thread thread = new Thread(runnable); thread.start(); } catch (Exception e) { e.printStackTrace(); } } public void closeServer() { locker = null; if (serverSocket != null && !serverSocket.isClosed()) { try { serverSocket.close(); } catch (IOException e) { e.printStackTrace(); } } } class Server implements Runnable { @Override public void run() { try { while (locker != null) { if (serverSocket == null || serverSocket.isClosed()) { continue; } //接收客户端的连接 Socket incoming = serverSocket.accept(); Runnable runnable = new ThreadClient(incoming); executorService.execute(runnable); } } catch (Exception e) { //此处有一种异常,当关掉Tomcat时,会去关闭ServerSocket对象, //从而抛出异常java.net.SocketException: socket closed, //原因是ServerSocket对象正在等待客户端连接或正在连接中 e.printStackTrace(); } } } class ThreadClient implements Runnable { private Socket incoming; private ThreadClient(Socket socket) { incoming = socket; } public void run() { InputStreamReader isr = null; BufferedReader br = null; OutputStreamWriter osw = null; BufferedWriter bw = null; try { isr = new InputStreamReader(incoming.getInputStream(), "UTF-8"); br = new BufferedReader(isr); osw = new OutputStreamWriter(incoming.getOutputStream(), "UTF-8"); bw = new BufferedWriter(osw); //读取客户端发送的数据 StringBuilder sb = new StringBuilder(); int c; while ((c = br.read()) != -1) { if (c != '2. 实现ServletContextListener监听接口并在实现方法中启动843端口监听类
') { sb.append((char) c); } else { break; } } String info = sb.toString(); System.out.println(String.format("客户端发送的数据:%s", info)); //接收到客户端请求之后,将策略文件发送出去 if (info.contains("")) { bw.write(" - 实现ServletContextListener监听接口并在实现方法中启动843端口监听类; "); bw.flush(); System.out.println(String.format("将安全策略文件发送至:%s", incoming.getInetAddress())); } else { bw.write("请求无法识别
- 编写MyServletContextListener类让其实现ServletContextListener接口,并实现其中的两个方法 "); bw.flush(); System.out.println(String.format("请求无法识别:%s", incoming.getInetAddress())); } } catch (IOException e) { e.printStackTrace(); } finally { try { if (br != null) { br.close(); } } catch (IOException e) { e.printStackTrace(); } try { if (isr != null) { isr.close(); } } catch (IOException e) { e.printStackTrace(); } try { if (bw != null) { bw.close(); } } catch (IOException e) { e.printStackTrace(); } try { if (osw != null) { osw.close(); } } catch (IOException e) { e.printStackTrace(); } try { if (incoming != null) { incoming.close(); } } catch (IOException e) { e.printStackTrace(); } } } }}
3. 编写页面进行调试
4. 启动应用进行测试
MyServletContextListener.java具体内容如下
package org.yuan.config;import javax.servlet.ServletContextEvent;import javax.servlet.ServletContextListener;import javax.servlet.annotation.WebListener;/** *
* Description:
** Author:jinshengyuan
* */@WebListenerpublic class MyServletContextListener implements ServletContextListener { private SocketService service; @Override public void contextInitialized(ServletContextEvent sce) { service = new SocketService(); service.initSocketServer(); } @Override public void contextDestroyed(ServletContextEvent sce) { service.closeServer(); }}
* Datetime: 2020-06-16 15:25 *index.html内容如下
Sample of web_socket.js // Set URL of your WebSocketMain.swf here: WEB_SOCKET_SWF_LOCATION = "WebSocketMain.swf"; // Set this to dump debug message from Flash to console.log: WEB_SOCKET_DEBUG = true; // Everything below is the same as using standard WebSocket. var ws; function init() { // Connect to Web Socket. // Change host/port here to your own Web Socket server. ws = new WebSocket("ws://localhost:2001/myChat"); // Set event handlers. ws.onopen = function() { output("onopen"); }; ws.onmessage = function(e) { // e.data contains received string. output("onmessage: " + e.data); }; ws.onclose = function() { output("onclose"); }; ws.onerror = function() { output("onerror"); }; } function onSubmit() { var input = document.getElementById("input"); // You can send message to the Web Socket using ws.send. ws.send(input.value); output("send: " + input.value); input.value = ""; input.focus(); } function onCloseClick() { ws.close(); } function output(str) { var log = document.getElementById("log"); var escaped = str.replace(/&/, "&").replace(//, ">").replace(/"/, """); // " log.innerHTML = escaped + "
" + log.innerHTML; } close启动SpringBoot应用后,浏览器中输入地址进行测试:http://localhost:2001
下一篇:文件服务器怎么组网查看?