SpringBoot之整合WebSocket服务并兼容IE8浏览器的方式

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. 启动应用进行测试

  1. SpringBoot整合WebSocket过程请查看 SpringBoot之WebSocket服务搭建;
  2. 以下WebSocket兼容IE8浏览器的方式就是在 SpringBoot之WebSocket服务搭建基础上完成的。

1. web-socket-js

  1. 为了兼容IE8浏览器,WebSocket采用Adobe Flash来实现,而Flash由于安全策略问题,会向TCP:843端口发送请求文件,服务器应该返回安全策略文件给客户端;

  2. 这里是使用开源项目web-socket-js对IE8中使用webSocket进行兼容适配与实现;

  3. web-socket-js官网地址:https://github.com/gimite/web-socket-js

1.下载web-socket-js

从官网中下载并提取swfobject.jsweb_socket.jsWebSocketMain.swf等三个文件

2. 配置

将上面三个文件放在SpringBoot静态资源目录下

  1. 在·src\main\resources\static目录下新建myjs文件夹,并将swfobject.jsweb_socket.js`放在myjs中
  2. WebSocketMain.swf放在跟目录src\main\resources\

2. FlashSocket安全服务策略文件843端口配置

1. 配置方式1_xxx.xml配置方式

此配置方式只需要两步:

  1. 编写一个flash安全服务策略文件监听843端口的监听器线程类;
  2. 在spring boot应用启动后,随即启动监听843端口的监听器线程;
  3. 配置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();}}@Overridepublic 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("<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();}}}
}
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;@Component
public class InitConfig implements CommandLineRunner {@Overridepublic void run(String... args) throws Exception {WebSocketPolicyListener webSocketPolicyListener = new WebSocketPolicyListener();new Thread(webSocketPolicyListener).start();}
}
3. 配置flash通信协议的策略文件

默认的策略文件名为crossdomain.xml;

  1. 这里我自己定义为ebsocket-policy.xml,并将此文件放在项目跟目录下;

  2. src\main\resources\websocket-policy.xml

websocket-policy.xml内容如下

<?xml version="1.0" encoding="UTF-8" ?>
<cross-domain-policy><site-control permitted-cross-domain-policies="all"/><allow-http-request-headers-from domain="*" headers="*"/><allow-access-from domain="*" to-ports="2001"/>
</cross-domain-policy>

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 {@Overridepublic 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 != '\0') {sb.append((char) c);} else {break;}}String info = sb.toString();System.out.println(String.format("客户端发送的数据:%s", info));//接收到客户端请求之后,将策略文件发送出去if (info.contains("<policy-file-request/>")) {bw.write("<cross-domain-policy><site-control permitted-cross-domain-policies=\"all\"/><allow-access-from domain=\"*\" to-ports=\"*\"/></cross-domain-policy>\0");bw.flush();System.out.println(String.format("将安全策略文件发送至:%s", incoming.getInetAddress()));} else {bw.write("请求无法识别\0");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();}}}}
}
2. 实现ServletContextListener监听接口并在实现方法中启动843端口监听类
  1. 实现ServletContextListener监听接口并在实现方法中启动843端口监听类;
  2. 编写MyServletContextListener类让其实现ServletContextListener接口,并实现其中的两个方法

MyServletContextListener.java具体内容如下

package org.yuan.config;import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;/*** <p>* Description: <br>* <p>* Author:jinshengyuan <br>* Datetime: 2020-06-16 15:25* </p>**/
@WebListener
public class MyServletContextListener implements ServletContextListener {private SocketService service;@Overridepublic void contextInitialized(ServletContextEvent sce) {service = new SocketService();service.initSocketServer();}@Overridepublic void contextDestroyed(ServletContextEvent sce) {service.closeServer();}
}

3. 编写页面进行调试

index.html内容如下

<!--Lincense: Public Domain
--><html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>Sample of web_socket.js</title><!-- Include these three JS files: --><script type="text/javascript" src="/myjs/swfobject.js"></script><script type="text/javascript" src="/myjs/web_socket.js"></script><script type="text/javascript">// 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(/&/, "&amp;").replace(/</, "&lt;").replace(/>/, "&gt;").replace(/"/, "&quot;"); // "log.innerHTML = escaped + "<br>" + log.innerHTML;}</script>
</head><body onload="init();"><form onsubmit="onSubmit(); return false;"><input type="text" id="input"><input type="submit" value="Send"><button onclick="onCloseClick(); return false;">close</button></form><div id="log"></div>
</body></html>

4. 启动应用进行测试

启动SpringBoot应用后,浏览器中输入地址进行测试:http://localhost:2001

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/699192.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

wordpress免费主题模板

免费大图wordpress主题 首页是一张大图的免费wordpress主题模板。简洁实用&#xff0c;易上手。 https://www.jianzhanpress.com/?p5857 wordpress免费模板 动态效果的wordpress免费模板&#xff0c;banner是动态图片效果&#xff0c;视觉效果不错。 https://www.jianzhan…

【深度学习】SSD 神经网络:彻底改变目标检测

一、说明 Single Shot MultiBox Detector &#xff08;SSD&#xff09; 是一项关键创新&#xff0c;尤其是在物体检测领域。在 SSD 出现之前&#xff0c;对象检测主要通过两阶段过程执行&#xff0c;首先识别感兴趣的区域&#xff0c;然后将这些区域分类为对象类别。这种方法虽…

RT-Thread 时钟 timer delay 相关

前言 此处,介绍对delay 时钟 timer 这几部分之间的关联和相关的知识点;本来只是想介绍一下 delay的,但是发现说到delay 不先 提到 先验知识 晶振\时钟\时钟节拍\定时器 好像没法解释透彻,所以就变成了 晶振\时钟\时钟节拍\定时器\delay 的很简单的概括一遍;并附带上能直接运行的…

Vue解决接口跨域

Vue解决接口跨域 一、vue.config.js配置文件二、全局路径 一、vue.config.js配置文件 const { defineConfig } require(vue/cli-service) module.exports defineConfig({transpileDependencies: true,//解决跨域devServer:{proxy:http://127.0.0.1:8888} })二、全局路径 im…

反序列化 [NPUCTF2020]ReadlezPHP1

打开题目 直接查看源代码 打开源代码发现了个./time.php?source 访问一下 审计代码&#xff1a; 现存在反序列化语句&#xff1a;$ppp unserialize($_GET["data"]);和执行漏洞&#xff1a;echo $b($a); 发现在__destruct()方法里面有 echo $b($a); 这个是php的…

Day4 javaweb开发——事务管理AOP

事务管理 事务是一组操作的集合&#xff0c;是一个不可分割的工作单位&#xff0c;这些操作要么同时成功&#xff0c;要么同时失败。 开启事务 start transaction / begin提交事务 commit回滚事务 rollback 删除部门时&#xff0c;要同时删除该部门下的员工 Transactional 注…

Stable Diffusion 模型分享:A-Zovya RPG Artist Tools(RPG 大师工具箱)

本文收录于《AI绘画从入门到精通》专栏&#xff0c;专栏总目录&#xff1a;点这里。 文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八 下载地址 模型介绍 A-Zovya RPG Artist Tools 模型是一个针对 RPG 训练的一个模型&#xff0c;可以生成一些 R…

基于springboot+vue的靓车汽车销售网站(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

Shiro 1.2.4反序列化漏洞

一、shiro描述 Apache Shiro是一个强大且易用的Java安全框架&#xff0c;执行身份验证、授权、密码和会话管理。使用Shiro的易于理解的API&#xff0c;可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序 二、漏洞原理 AES加密的密钥Key被硬…

python递归算法

递归算法 一、嵌套调用的过程二、递归的基本原则1、递归的基本原则2、无限递归调用3、正常递归调用4、阶乘问题5、力扣&#xff1a;231. 2 的幂6、力扣面试题 08.05. 递归乘法7、力扣、326. 3 的幂8、力扣342. 4的幂 一、嵌套调用的过程 def show1():print("show 1 run s…

自学Python第十八天-自动化测试框架(二):DrissionPage、appium

自学Python第十八天-自动化测试框架&#xff08;二&#xff09;&#xff1a;DrissionPage、appium DrissionPage环境和安装配置准备工作简单的使用示例控制浏览器收发数据包模式切换 浏览器模式创建浏览器对象访问页面加载模式none 模式技巧 获取页面信息页面交互查找元素ele()…

uniapp腾讯地图JavaScript Api,H5端和原生APP端可用

因项目需要&#xff0c;在uniapp中集成使用腾讯地图&#xff0c;为了方便维护&#xff0c;希望通过一套代码实现H5和APP同时可用。H5显示相对简单&#xff0c;APP端比较麻烦&#xff0c;记录下实现过程 一、集成步骤 1.使用 renderjs script标签使用renderjs&#xff0c;因为…

一文了解LM317T的引脚介绍、参数解读

LM317T是一种线性稳压器件&#xff0c;它具有稳定输出电压的特性。LM317T可以通过调整其输出电阻来确保输出电压的稳定性&#xff0c;因此被广泛应用于各种电子设备中。 LM317T引脚图介绍 LM317T共有3个引脚&#xff0c;分别是&#xff1a; 输入引脚&#xff08;输入电压V_in&…

软件应用场景,物流货运配货单打印模板软件单据打印查询管理系统软件教程

软件应用场景&#xff0c;物流货运配货单打印模板软件单据打印查询管理系统软件教程 一、前言 以下软件以 佳易王物流快运单打印查询管理系统软件V17.1 软件文件下载可以点击最下方官网卡片——软件下载——试用版软件下载 1、打印模式可以分为 直打模式和套打模式 直打模…

MySQL-----多表操作

介绍 实际开发中&#xff0c;一个项目通常需要很多张表才能完成。例如:一个商城项目就需要分类表(category)、商品表(products)、订单表(orders)等多张表。且这些表的数据之间存在一定的关系&#xff0c;接下来我们将在单表的基础上&#xff0c;一起学习多表方面的知识。 一 多…

CentOS 7更换yum源|详细步骤

安装httpd时说获取不到httpd需要的安装包&#xff0c;就知道又是yum源的问题&#xff0c;按照下面的步骤更换yum源&#xff0c;亲测有效&#xff01; 1、先备份/etc/yum.repos.d/CentOS-Base.repo文件&#xff0c;以防文件修改出问题后无法复原。 cd /etc/yum.repos.d mv Cent…

使用HiveMQ实现Android MQTT

MQTT官网&#xff1a;https://mqtt.org/ 百度Android MQTT&#xff0c;或者B站上搜索&#xff0c;发现大多使用https://github.com/eclipse/paho.mqtt.android&#xff0c;这是Eclipse的一个Android MQTT客户端实现库&#xff0c;但是我发现这个库在运行到高版本的手机上时报错…

自动驾驶中的障碍物时间对齐法

描述 自动驾驶算法使用的系统往往不是实时系统&#xff0c;因此每个节点间拿到的数据可能不是同一时间的数据&#xff0c;从而造成系统误差&#xff0c;针对这一现象&#xff0c;工程上往往采用时间对齐内插外推法。这里我们用感知障碍物来举例。 自动驾驶系统有许多重要模块…

Rust核心:【所有权】相关知识点

rust在内存资源管理上采用了&#xff08;先进优秀&#xff1f;算吗&#xff09;但特立独行的设计思路&#xff1a;所有权。这是rust的核心&#xff0c;贯穿在整个rust语言的方方面面&#xff0c;并以此为基点来重新思考和重构软件开发体系。 涉及到的概念点&#xff1a;借用&am…

C++线性搜索

#include <iostream> #include <vector>int linearSearch(const std::vector<int>& arr, int target) {for (int i 0; i < arr.size(); i) {if (arr[i] target) {return i; // 返回找到元素的索引}}return -1; // 如果没有找到目标元素&#xff0…