spring boot整合websocket
  jqO5822mAt6g 2023年11月13日 33 0

1、引入包

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

2、添加配置文件

package com.ruoyi.common.config;

import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;

@Configuration
public class WebSocketConfig implements ServletContextInitializer {
    /**
     * 这个bean的注册,用于扫描带有@ServerEndpoint的注解成为websocket,如果你使用外置的tomcat就不需要该配置文件
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {

    }
}

3、配置入口

package com.ruoyi.web.controller.api;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;

@ServerEndpoint("/api/webSocketSever/{userId}")
@Component
@Slf4j
public class WebSocketSever {
    // 与某个客户端的连接会话,需要通过它来给客户端发送数据
    private Session session;

    // session集合,存放对应的session
    private static ConcurrentHashMap<Integer, Session> sessionPool = new ConcurrentHashMap<>();

    // concurrent包的线程安全Set,用来存放每个客户端对应的WebSocket对象。
    private static CopyOnWriteArraySet<WebSocketSever> webSocketSet = new CopyOnWriteArraySet<>();

    /**
     * 建立WebSocket连接
     *
     * @param session
     * @param userId 用户ID
     */
    @OnOpen
    public void onOpen(Session session, @PathParam(value = "userId") Integer userId) {
        log.info("WebSocket建立连接中,连接用户ID:{}", userId);
        try {
            Session historySession = sessionPool.get(userId);
            // historySession不为空,说明已经有人登陆账号,应该删除登陆的WebSocket对象
            if (historySession != null) {
                webSocketSet.remove(historySession);
                historySession.close();
            }
        } catch (IOException e) {
            log.error("重复登录异常,错误信息:" + e.getMessage(), e);
        }
        // 建立连接
        this.session = session;
        webSocketSet.add(this);
        sessionPool.put(userId, session);
        log.info("建立连接完成,当前在线人数为:{}", webSocketSet.size());
    }

    /**
     * 发生错误
     *
     * @param throwable e
     */
    @OnError
    public void onError(Throwable throwable) {
        throwable.printStackTrace();
    }

    /**
     * 连接关闭
     */
    @OnClose
    public void onClose() {
        webSocketSet.remove(this);
        log.info("连接断开,当前在线人数为:{}", webSocketSet.size());
    }

    /**
     * 接收客户端消息
     *
     * @param message 接收的消息
     */
    @OnMessage
    public void onMessage(String message) {
        JSONObject jsonObject = JSONObject.parseObject(message);
        Integer to = jsonObject.getInteger("to");
        String message1 = jsonObject.getString("message");
        sendMessageByUser(to,message1);
        log.info("收到客户端发来的消息:{}", message);


    }

    /**
     * 推送消息到指定用户
     *
     * @param userId  用户ID
     * @param message 发送的消息
     */
    public static void sendMessageByUser(Integer userId, String message) {
        log.info("用户ID:" + userId + ",推送内容:" + message);
        Session session = sessionPool.get(userId);
        try {
            session.getBasicRemote().sendText(message);
        } catch (IOException e) {
            log.error("推送消息到指定用户发生错误:" + e.getMessage(), e);
        }
    }

    /**
     * 群发消息
     *
     * @param message 发送的消息
     */
    public static void sendAllMessage(String message) {
        log.info("发送消息:{}", message);
        for (WebSocketSever webSocket : webSocketSet) {
            try {
                webSocket.session.getBasicRemote().sendText(message);
            } catch (IOException e) {
                log.error("群发消息发生错误:" + e.getMessage(), e);
            }
        }
    }
}

前端进行访问测试是否能够链接成功 入口链接为  ws://127.0.0.1:7788/api/webSocketSever/1  

使用postman websocket 接口进行访问,即可发现提示 链接成功! 参数 1 代表的是 当前用户的标识!

下面是一个简单的html 页面对话

对话1:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>用户1咨询</title>
	<script type="text/javascript" src="https://code.jquery.com/jquery-3.7.0.min.js" ></script>
</head>
<body>
	<p id="message"></p>
	<form id="clientChat">
		<input type="text" style="display: none;" id="userName"  />
		<input type="text" style="display: none;" id="targetUserName" />
		<input type="text" id="sendMsg"></input>
		<button type="button" onclick="send()">发送</button>
	</form>
</body>
<script>
var websocket = null;

var userId = null;

//判断当前浏览器是否支持WebSocket
if('WebSocket' in window){
    websocket = new WebSocket("ws://127.0.0.1:7788/api/webSocketSever/1");
} else {
    alert("Don't support websocket!")
}

//连接发生错误的回调方法
websocket.onerror = function(){
    alert("Connect error!");
};

//连接成功建立的回调方法
websocket.onopen = function(event){
    setMessageInnerHTML("连接已建立!");
}

//接收到消息的回调方法
websocket.onmessage = function(event){
	var result = event.data
     //判断是否有消息
	if(result != null){
		setMessageInnerHTML(result);
	}
	// var ob = JSON.parse(result)
	// //判断用户状态
	// if(ob.state != undefined && ob.state != "success"){
	// 	setMessageInnerHTML("非法连接!");
	// 	websocket.close();
	// }
	
	// //判断是否有消息
	// if(ob.msg != undefined){
	// 	setMessageInnerHTML(ob.msg);
	// }
}

//连接关闭的回调方法
websocket.onclose = function(){
    setMessageInnerHTML("close");
}

//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
window.onbeforeunload = function(){
    websocket.close();
}

//将消息显示在网页上
function setMessageInnerHTML(innerHTML){
    document.getElementById('message').innerHTML += innerHTML + '<br/>';
}

//关闭连接
function closeWebSocket(){
    websocket.close();
}

//发送消息
function send(){
	var sendMsg = $("#sendMsg").val();
    var message = {
            "message":sendMsg,
            "to":2
        };
	setMessageInnerHTML("我 :" + sendMsg)
    var ss = websocket.send(JSON.stringify(message));
    console.log(ss);
    $("#sendMsg").val("");
}
</script>
</html>

对话2:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>用户2咨询</title>
	<script type="text/javascript" src="https://code.jquery.com/jquery-3.7.0.min.js" ></script>
</head>
<body>
	<p id="message"></p>
	<form id="clientChat">
		<input type="text" style="display: none;" id="userName"  />
		<input type="text" style="display: none;" id="targetUserName" />
		<input type="text" id="sendMsg"></input>
		<button type="button" onclick="send()">发送</button>
	</form>
</body>
<script>
var websocket = null;

var userId = null;

//判断当前浏览器是否支持WebSocket
if('WebSocket' in window){
    websocket = new WebSocket("ws://127.0.0.1:7788/api/webSocketSever/2");
} else {
    alert("Don't support websocket!")
}

//连接发生错误的回调方法
websocket.onerror = function(){
    alert("Connect error!");
};

//连接成功建立的回调方法
websocket.onopen = function(event){
    setMessageInnerHTML("连接已建立!");
}

//接收到消息的回调方法
websocket.onmessage = function(event){
	var result = event.data
     //判断是否有消息
	if(result != null){
		setMessageInnerHTML(result);
	}
	// var ob = JSON.parse(result)
	// //判断用户状态
	// if(ob.state != undefined && ob.state != "success"){
	// 	setMessageInnerHTML("非法连接!");
	// 	websocket.close();
	// }
	
	// //判断是否有消息
	// if(ob.msg != undefined){
	// 	setMessageInnerHTML(ob.msg);
	// }
}

//连接关闭的回调方法
websocket.onclose = function(){
    setMessageInnerHTML("close");
}

//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
window.onbeforeunload = function(){
    websocket.close();
}

//将消息显示在网页上
function setMessageInnerHTML(innerHTML){
    document.getElementById('message').innerHTML += innerHTML + '<br/>';
}

//关闭连接
function closeWebSocket(){
    websocket.close();
}

//发送消息
function send(){
	var sendMsg = $("#sendMsg").val();
	var message = {
            "message":sendMsg,
            "to":1
        };
	setMessageInnerHTML("我 :" + sendMsg)
	 
    var ss = websocket.send(JSON.stringify(message));
    console.log(ss);
    $("#sendMsg").val("");
}
</script>
</html>

以上就是 一个spring boot 整合websockte 主体实现逻辑,可以继续在其中进行增加自己的逻辑业务进行开发

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月13日 0

暂无评论

推荐阅读
  D04qQxYJZ4A6   2023年11月19日   24   0   0 mysqljava读写分离
  UP4ONKOBnkdD   2023年11月28日   25   0   0 java
  9JCEeX0Eg8g4   2023年12月10日   30   0   0 应用程序javaApache
  P3nxyT0LRuwj   2023年11月19日   28   0   0 javawar包jar
  KRsXEGSB49bk   2023年11月27日   29   0   0 javaApache
  xwGmYGXf1w4S   2023年11月22日   43   0   0 tomcatjavaApache