第一步:
首先得明白什么是wss协议:
可以看这篇文章:WSS、SSL 和 https 之间的关系
第二步:
先拿到ssl证书:我这边是用的阿里云的免费证书具体获取方法如下:
先登录阿里云官网找到SSL证书选项,然后申请免费证书,然后下载tomcat证书。
可以参考:阿里云申请免费 SSL证书 https 的图文教程_林中明月间丶-CSDN博客_阿里云申请免费ssl证书
将下载的证书压缩包解压,找到后缀为.pfx的证书文件导入我们的springboot项目,如图:
然后在springboot的配置文件里面配置相应的属性(证书密码在解压后的pfx-password.txt文件中可以查看),我这边是配置了两个端口http和https都能访问该项目,同理ws和wss协议也都是支持的。
server.ssl.key-store=classpath:证书名称.pfx # 密码 server.ssl.key-store-password=证书密码 # 秘钥证书库类型 server.ssl.keyStoreType=PKCS12 #这里先放一个参数,一会儿再程序中直接@Value获取 myhttp.port=9097 # 此端口为HTTPS端口 server.port=9095 在这里插入代码片
添加依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency>
import com.wanma.display.center.ds.DynamicDataSourceRegister; import org.apache.catalina.Context; import org.apache.catalina.connector.Connector; import org.apache.tomcat.websocket.server.WsSci; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; import org.springframework.boot.web.servlet.server.ServletWebServerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication @Import(DynamicDataSourceRegister.class) @EnableScheduling public class DisplayCenterApplication { public static void main(String[] args) { SpringApplication.run(DisplayCenterApplication.class, args); } @Value("${myhttp.port}") private Integer httpPort; @Bean public ServletWebServerFactory servletContainer() { TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory(); tomcat.addAdditionalTomcatConnectors(createHTTPConnector()); return tomcat; } private Connector createHTTPConnector() { Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol"); connector.setScheme("http"); connector.setSecure(false); connector.setPort(httpPort); return connector; } /** * 创建wss协议接口 * * @return */ @Bean public TomcatContextCustomizer tomcatContextCustomizer() { System.out.println("websocket init"); return new TomcatContextCustomizer() { @Override public void customize(Context context) { System.out.println("init customize"); context.addServletContainerInitializer(new WsSci(), null); } }; } }
添加WebSocketConfig 配置类
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.server.standard.ServerEndpointExporter; @Configuration public class WebSocketConfig { @Bean public ServerEndpointExporter serverEndpointExporter(){ return new ServerEndpointExporter(); } }
然后在启动项目。
到这里所有的配置都已经结束了,接下来就是测试了。
websocket 代码:
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import javax.websocket.OnClose; import javax.websocket.OnError; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @ServerEndpoint("/ws/{token}") // 指定建立连接使用的URI @Component public class WebSocketServer { private final Logger LOGGER = LoggerFactory.getLogger(this.getClass()); /** * 用于存储Session的Map,key为连接标识 */ public static final Map<String, Session> SESSION_MAP = new ConcurrentHashMap<>(); /** * 连接建立 * 从请求的URL:ws://localhost:8091/ws/{token}参数里面获取标识token */ @OnOpen public void onOpen(@PathParam("token") String token, Session session){ LOGGER.info("长连接已建立,用户:" + token); System.out.println("长连接已建立,用户:" + token); // 存储连接session,在需要用的地方直接使用 SESSION_MAP.put(token,session); } // /** // * 收消息 // */ // @OnMessage // public void onMessage(){ // } /** * 连接断开 * @param token * @param session */ @OnClose public void onClose(@PathParam("token") String token, Session session){ LOGGER.info("长连接已断开,用户:" + token); System.out.println("长连接已断开,用户:" + token); SESSION_MAP.remove(token); } /** * 长连接出现异常 */ @OnError public void onError(Throwable throwable){ LOGGER.info("长连接出现异常:" + throwable.getMessage()); System.out.println("长连接出现异常:" + throwable.getMessage()); } }
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>websocket通讯</title> </head> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script> <script> var socket; function openSocket() { if (typeof (WebSocket) == "undefined") { console.log("您的浏览器不支持WebSocket"); } else { console.log("您的浏览器支持WebSocket"); //实现化WebSocket对象,指定要连接的服务器地址与端口 建立连接 //等同于socket = new WebSocket("ws://localhost:8888/xxxx/im/25"); //var socketUrl="${request.contextPath}/im/"+$("#userId").val(); //var socketUrl="http://app.boruisijj.com:9099/demo/imserver/"+$("#userId").val(); var socketUrl = "https://localhost:9093/websocket/" + $("#userId").val(); socketUrl = socketUrl.replace("https", "wss").replace("http", "ws"); console.log(socketUrl); if (socket != null) { socket.close(); socket = null; } socket = new WebSocket(socketUrl); //打开事件 socket.onopen = function () { console.log("websocket已打开"); //socket.send("这是来自客户端的消息" + location.href + new Date()); }; //获得消息事件 socket.onmessage = function (msg) { console.log(msg.data); //发现消息进入 开始处理前端触发逻辑 }; //关闭事件 socket.onclose = function () { console.log("websocket已关闭"); }; //发生了错误事件 socket.onerror = function () { console.log("websocket发生了错误"); } } } function sendMessage() { if (typeof (WebSocket) == "undefined") { console.log("您的浏览器不支持WebSocket"); } else { console.log("您的浏览器支持WebSocket"); console.log($("#contentText").val()); socket.send($("#contentText").val()); } } </script> <body> <p>【userId】: <div><input id="userId" name="userId" type="text" value="10"></div> <p>【toUserId】: <div><input id="toUserId" name="toUserId" type="text" value="20"></div> <p>【toUserId】: <div><input id="contentText" name="contentText" type="text" value="hello websocket"></div> <p>【操作】: <div><a οnclick="openSocket()">开启socket</a></div> <p>【操作】: <div><a οnclick="sendMessage()">发送消息</a></div> </body> </html>
————————————————
版权声明:本文为CSDN博主「林深时见鹿_Mr_Li」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_40902067/article/details/125421291