第一步:

首先得明白什么是wss协议:

可以看这篇文章:WSS、SSL 和 https 之间的关系


第二步:

先拿到ssl证书:我这边是用的阿里云的免费证书具体获取方法如下:


先登录阿里云官网找到SSL证书选项,然后申请免费证书,然后下载tomcat证书。

可以参考:阿里云申请免费 SSL证书 https 的图文教程_林中明月间丶-CSDN博客_阿里云申请免费ssl证书

image.png

将下载的证书压缩包解压,找到后缀为.pfx的证书文件导入我们的springboot项目,如图:

image.png

然后在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