SpringBoot整合WebSocket详细教程

这篇具有很好参考价值的文章主要介绍了SpringBoot整合WebSocket详细教程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

预期效果

SpringBoot整合WebSocket详细教程

SpringBoot整合WebSocket详细教程
共开启两个页面,实现一对一聊天。

服务端代码:https://gitee.com/lianaozhe/springboot-websocket.git

代码实现逻辑

服务端

导入相关依赖:

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

        <!-- hutool 工具包,各种封装功能 一应俱全-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.5</version>
        </dependency>

WebSocketConfig配置类:

package com.web.config;

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

/**
 * @ClassName WebSocketConfig
 * @Description TODO
 * @Author laz
 * @Date 2023/4/26 16:18
 * @Version 1.0
 */
@Configuration
public class WebSocketConfig {

    /**
     * 	注入ServerEndpointExporter,
     * 	这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
    
}

WebSocket操作类:

package com.web.websocket;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * @ClassName WebSocket
 * @Description TODO
 * @Author laz
 * @Date 2023/4/26 16:20
 * @Version 1.0
 */
@Component
@Slf4j
@ServerEndpoint("/websocket/{userId}")
public class WebSocket {

    //与某个客户端的连接会话,需要通过它来给客户端发送数据
    private Session session;
    /**
     * 用户ID
     */
    private String userId;

    /**
     * 用来存放每个客户端对应的MyWebSocket对象。
     */
    private static CopyOnWriteArraySet<WebSocket> webSockets =new CopyOnWriteArraySet<>();
    // 用来存在线连接用户信息
    private static ConcurrentHashMap<String,Session> sessionPool = new ConcurrentHashMap<String,Session>();

    /**
     * 链接成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam(value="userId")String userId) {
        try {
            this.session = session;
            this.userId = userId;
            webSockets.add(this);
            sessionPool.put(userId, session);
            log.info("【websocket消息】有新的连接,用户id是【{}】总数为【{}】",userId,webSockets.size());
        } catch (Exception e) {
        }
    }

    /**
     * 链接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        try {
            webSockets.remove(this);
            sessionPool.remove(this.userId);
            log.info("【websocket消息】连接断开,总数为:"+webSockets.size());
        } catch (Exception e) {
        }
    }
    /**
     * 收到客户端消息后调用的方法
     *
     * @param message
     * @param message
     */
    @OnMessage
    public void onMessage(String message) {
        log.info("【websocket消息】收到客户端消息:"+message);
        JSONObject jsonObject = JSONUtil.parseObj(message);
        Object toUserId = jsonObject.get("toUserId");
        Session session = sessionPool.get(toUserId);

        session.getAsyncRemote().sendText(JSONUtil.toJsonStr(jsonObject.get("msg")));

    }

    /** 发送错误时的处理
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {

        log.error("用户错误,原因:"+error.getMessage());
        error.printStackTrace();
    }


    // 此为广播消息
    public void sendAllMessage(String message) {
        log.info("【websocket消息】广播消息:"+message);
        for(WebSocket webSocket : webSockets) {
            try {
                if(webSocket.session.isOpen()) {
                    webSocket.session.getAsyncRemote().sendText(message);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    // 此为单点消息
    public void sendOneMessage(String userId, String message) {
        Session session = sessionPool.get(userId);

        if (session != null&&session.isOpen()) {
            try {
                log.info("【websocket消息】 单点消息:"+message);
                session.getAsyncRemote().sendText(message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    // 此为单点消息(多人)
    public void sendMoreMessage(String[] userIds, String message) {
        for(String userId:userIds) {
            Session session = sessionPool.get(userId);
            if (session != null&&session.isOpen()) {
                try {
                    log.info("【websocket消息】 单点消息:"+message);
                    session.getAsyncRemote().sendText(message);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

    }

}

TestController测试接口类:

package com.web.controller;

import com.web.websocket.WebSocket;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @ClassName TestController
 * @Description TODO
 * @Author laz
 * @Date 2023/4/26 16:23
 * @Version 1.0
 */
@RestController
@RequestMapping("web")
public class TestController {

    @Autowired
    private WebSocket webSocket;

    @RequestMapping("test")
    public String test(String userId,String msg){
        webSocket.sendOneMessage(userId,msg);
        return "成功";
    }
}

客户端

test.html文件:

<!doctype html>
<html lang="zh-CN">
	<head>
		<!-- 必须的 meta 标签 -->
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

		<!-- Bootstrap 的 CSS 文件 -->
		<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css"
			integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">



		<title>WebSocket1</title>

		<style>
			form {
				width: 820px;
				margin: auto;
			}

			.div1 {
				width: 820px;
				height: 500px;
				border: #000000;
				border-width: thin;
				border-style: solid;
			}

			.div2 {
				text-align: center;
				width: 800px;
				height: 50px;
			}
		</style>

		<script>
			function clearData() {
				$("#div1").html("");
			}


			var socket;

			function openSocket() {
				if (typeof(WebSocket) == "undefined") {
					console.log("您的浏览器不支持WebSocket");
				} else {
					console.log("您的浏览器支持WebSocket");

					//websocket地址
					var socketUrl = "ws://localhost:8088/websocket/20";
					console.log(socketUrl);
					if (socket != null) {
						socket.close();
						socket = null;
					}
					socket = new WebSocket(socketUrl);
					//打开事件
					socket.onopen = function() {
						console.log("websocket已打开");
						$("#div1").append("websocket已打开" + "<br \>");
					};
					//获得消息事件
					socket.onmessage = function(msg) {
						console.log(msg.data);
						$("#div1").append("接收到消息:" + msg.data + "<br \>");

					};
					//关闭事件
					socket.onclose = function() {
						console.log("websocket已关闭");
						$("#div1").append("websocket已关闭" + "<br \>");
					};
					//发生了错误事件
					socket.onerror = function() {
						console.log("websocket发生了错误");
						$("#div1").append("websocket发生了错误" + "<br \>");
					}
				}
			}

			function sendMsg() {
				if (typeof(WebSocket) == "undefined") {
					console.log("您的浏览器不支持WebSocket");
				} else {
					console.log("您的浏览器支持WebSocket");
					console.log('{"toUserId":"' + $("#toUserId").val() + '","msg":"' + $("#msg").val() + '"}');
					socket.send('{"toUserId":"' + $("#toUserId").val() + '","msg":"' + $("#msg").val() + '"}');

					var msg = document.getElementById("msg").value;
					$("#div1").append("发送消息:" + msg + "<br \>");
					document.getElementById("msg").value = "";
				}


			}
		</script>

	</head>
	<body>

		<h1 align="center">WebSocket测试Demo</h1><br />
		<form class="form-inline">

			<div class="form-group mx-sm-3 mb-2">
				<label for="toUserId" class="sr-only">toUserId</label>
				<input type="text" class="form-control" id="toUserId" placeholder="toUserId">
			</div>
			<div class="form-group mb-2">
				<label for="msg" class="sr-only">消息內容</label>
				<input type="text" class="form-control" id="msg" placeholder="消息內容">
			</div>
			<div class="form-group mx-sm-3 mb-2">
				<button type="button" class="btn btn-primary" onclick="openSocket()">开启socket</button>
			</div>
			<div class="form-group mx-sm-3 mb-2">
				<button type="button" class="btn btn-danger" onclick="sendMsg()">发送消息</button>
			</div>
			<div class="form-group mx-sm-3 mb-2">
				<button type="button" class="btn btn-secondary" onclick="clearData()">清空内容</button>
			</div>
			<div class="div2"></div>
			<div class="div1" id="div1"></div>

		</form>

	</body>

	<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js"
		integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous">
	</script>
	<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js"
		integrity="sha384-7ymO4nGrkm372HoSbq1OY2DP4pEZnMiA+E0F3zPr+JQQtQ82gQ1HPY3QIVtztVua" crossorigin="anonymous">
	</script>

</html>

SpringBoot整合WebSocket详细教程
复制test.html文件为test2.html文件,将上面的userId由’20’改为’10’,后面测试使用。

测试

测试一

运行服务端项目,打开test.html,点击’开启socket’按钮(一定要先开启socket连接,否则无法接收到消息)。

SpringBoot整合WebSocket详细教程

可以看到,服务端与客户端已建立了连接。

然后调用我们的测试接口:

SpringBoot整合WebSocket详细教程

然后观察test.html页面:

SpringBoot整合WebSocket详细教程
可以看到,客户端的用户20成功接收到服务端发来的信息。

测试二

打开test2.html,同样点击’开启socket’,与服务端建立连接。

此时用test2.html给test.html发送一条消息。

SpringBoot整合WebSocket详细教程
SpringBoot整合WebSocket详细教程

可以看到,此时两个页面直接已经可以进行一对一的聊天了。

代码已上传到git:https://gitee.com/lianaozhe/springboot-websocket.git文章来源地址https://www.toymoban.com/news/detail-427703.html

到了这里,关于SpringBoot整合WebSocket详细教程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 《SpringBoot篇》18.SpringBoot整合Memcached缓存超详细教程

    陈老老老板 说明:工作了,学习一些新的技术栈和工作中遇到的问题,边学习边总结,各位一起加油。需要注意的地方都标红了,还有资源的分享. 一起加油。 本文是介绍Memcached与SpringBoot整合 整合之前先大致了解一下Memcached,是一个​ 免费开源的、高性能的、具有分布式内

    2024年02月03日
    浏览(49)
  • SpringBoot整合SpringSecurity详细教程(实战开发讲解)

    今天小编使用到了SpringBoot+SpringSecurity进行公司项目开发,之前使用到项目都是采用xml配置来整合SpringSecurity,对于第一次使用SpringBoot整合SpringSecurity也是比较陌生,过程中也是遇到各种各样的问题,在CSDN的知识海洋中遗留的相关的整合教程也是五花八门,找一篇完整的教程简

    2024年02月15日
    浏览(42)
  • Elasticsearch安装、使用,Springboot整合Elasticsearch详细教程

    Elasticsearch 是一个分布式、RESTful 风格的搜索和数据分析引擎,能够实现近乎实时的搜索。 Elasticsearch官网 https://www.elastic.co/cn/ 这篇文章主要简单介绍一下Elasticsearch,Elasticsearch的java API博主也在学习中,文章会持续更新~ 目录 第一步:下载Elasticsearch 下载7.6.2版本 下载其他版本

    2024年02月04日
    浏览(35)
  • SpringBoot 整合 clickhouse和mysql 手把手教程全网最详细

    最近做一个项目 需要 整合mysql clickhouse 多数据源 后台用的是ruoyi框架 需要注意的是官网不建议使用ru.yandex.clickhouse驱动,应该改成com.clickhouse驱动,并且推荐使用0.3.2以上的版本 重点在@DataSource(value = DataSourceType.SLAVE) 注解上 在这里切换从库代表这个类里面的方法都切换成从库

    2024年02月06日
    浏览(45)
  • SpringBoot整合多数据源,并支持动态新增与切换(详细教程)

    推荐文章:     1、springBoot对接kafka,批量、并发、异步获取消息,并动态、批量插入库表;     2、SpringBoot用线程池ThreadPoolTaskExecutor异步处理百万级数据;     3、java后端接口API性能优化技巧     4、SpringBoot+MyBatis流式查询,处理大规模数据,提高系统的性能和响应能力。 一

    2024年02月10日
    浏览(43)
  • docker安装grafana,prometheus,exporter以及springboot整合详细教程(GPE)

    springboot项目ip:192.168.168.1 测试服务器ip:192.168.168.81 文章来自互联网,自己略微整理下,更容易上手,方便自己,方便大家 最终效果: node springboot docker pull prom/node-exporter docker pull prom/mysqld-exporter docker pull google/cadvisor docker pull prom/prometheus docker pull grafana/grafana   访问url: http://192.168

    2024年02月10日
    浏览(43)
  • WebSocket--整合springboot

    目录 握手拦截器 WebSocket处理程序 HttpSessionHandshakelnterceptor (抽象类):   握手拦截器,在握手前后添加操作 AbstractWebSocketHandler (抽象类) :   WebSocket处理程序,监听连接前,连接中,连接后WebSocketConfigurer (接口):    配置程序,比如配置监听哪个端口,上面的握手拦截器,处理

    2024年01月16日
    浏览(61)
  • SpringBoot整合Websocket(Java websocket怎么使用)

    WebSocket 是一种基于 TCP 协议的全双工通信协议,可以在浏览器和服务器之间建立 实时、双向的数据通信 。可以用于在线聊天、在线游戏、实时数据展示等场景。与传统的 HTTP 协议不同,WebSocket 可以保持 长连接 ,实时传输数据,避免了频繁的 HTTP 请求和响应,节省了网络带

    2024年02月10日
    浏览(41)
  • 【WebSocket】SpringBoot整合WebSocket实现聊天室(一)

    目录 一、准备 1、引入依赖 2、创建配置类 二、相关注解 首先我们需要在项目中引入依赖,有两种方式。第一种我们可以在创建Spring Boot项目时搜索WebSocket然后勾选依赖 第二种是我们可以直接在项目的pom.xml文件中插入以下依赖 我们需要进行如下配置 ServerEndpointExporter 是一个

    2024年02月13日
    浏览(49)
  • WebSocket整合springboot显示进度条

    SpringBoot整合WebScoket显示进度条 - 钟小嘿 - 博客园 对于大文件上传解析,若直接上传,会超时,可使用WebSocket长链接方式实时显示文件的上传状态,实际上是从文件上传到内容解析完成存入数据库的过程,各个阶段的进度可自定义。 本文使用SpringBoot+WebSocket+vue2.0+Element+nginx实

    2024年02月14日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包