前端测试springboot websocket订阅示例代码

时间: 2023-11-17 14:01:24 浏览: 34
以下是一个前端测试Spring Boot WebSocket订阅示例代码: ```javascript var socket = new WebSocket('ws://localhost:8080/chat'); socket.onopen = function(event) { console.log('WebSocket is connected.'); }; socket.onmessage = function(event) { console.log('Received message: ' + event.data); }; socket.onclose = function(event) { console.log('WebSocket is closed.'); }; // 订阅聊天室 socket.send(JSON.stringify({ 'type': 'subscribe', 'room': 'chatroom' })); // 发送消息 socket.send(JSON.stringify({ 'type': 'message', 'room': 'chatroom', 'content': 'Hello, world!' })); ``` 这段代码创建了一个WebSocket连接,并订阅了名为“chatroom”的聊天室。它还发送了一条消息到该聊天室。你可以根据自己的需求修改代码。
相关问题

springboot 动态websocket

Spring Boot 支持使用 Spring WebSocket 模块来实现 WebSocket 功能。在 Spring WebSocket 中,我们可以通过实现 WebSocketHandler 接口来处理 WebSocket 请求,也可以使用 @Controller 注解和 @MessageMapping 注解来处理 WebSocket 请求。 动态 WebSocket 可以通过在后端使用 WebSocketSession 对象动态向前端推送数据。我们可以在后端创建一个 WebSocketSession 对象,然后将其存储在一个 Map 中,当需要向前端推送数据时,可以根据前端的连接 ID 从 Map 中获取相应的 WebSocketSession 对象,然后使用该对象向前端推送数据。 下面是一个使用 Spring WebSocket 实现动态 WebSocket 的示例代码: ```java @Controller public class WebSocketController { private static final Map<String, WebSocketSession> sessions = new ConcurrentHashMap<>(); @Autowired private SimpMessagingTemplate messagingTemplate; @MessageMapping("/connect") public void connect(Principal principal, WebSocketSession session) throws Exception { sessions.put(principal.getName(), session); } @MessageMapping("/push") public void push(Principal principal, String message) throws Exception { WebSocketSession session = sessions.get(principal.getName()); if (session != null && session.isOpen()) { messagingTemplate.convertAndSendToUser(principal.getName(), "/topic/push", message); } } @MessageMapping("/disconnect") public void disconnect(Principal principal) throws Exception { sessions.remove(principal.getName()); } } ``` 在上述代码中,我们使用了 @Controller 注解来标注 WebSocketController 类,并使用 @MessageMapping 注解来标注处理 WebSocket 请求的方法。在 connect 方法中,我们将 WebSocketSession 对象存储在 sessions Map 中,并在 push 方法中使用 messagingTemplate 对象向前端推送数据。disconnect 方法用于在断开连接时从 sessions Map 中移除 WebSocketSession 对象。 在前端实现时,我们可以使用 Stomp.js 库来实现 WebSocket 连接和消息推送。下面是一个使用 Stomp.js 实现动态 WebSocket 的示例代码: ```javascript var stompClient = null; function connect() { var socket = new SockJS('/websocket'); stompClient = Stomp.over(socket); stompClient.connect({}, function(frame) { stompClient.subscribe('/user/topic/push', function(message) { var data = JSON.parse(message.body); // 处理推送的数据 }); stompClient.send('/app/connect'); }); } function push(data) { stompClient.send('/app/push', {}, data); } function disconnect() { stompClient.send('/app/disconnect'); stompClient.disconnect(); } ``` 在上述代码中,我们使用 connect 方法来建立 WebSocket 连接,使用 push 方法来向后端推送数据,使用 disconnect 方法来断开 WebSocket 连接。在 connect 方法中,我们使用 Stomp.over 方法创建一个 Stomp 客户端,并使用 subscribe 方法来订阅推送消息。在 push 方法中,我们使用 send 方法来向后端推送数据。在 disconnect 方法中,我们使用 send 方法来通知后端断开 WebSocket 连接,并使用 disconnect 方法来关闭 Stomp 客户端。

springboot+vue+websocket+redis实现单聊代码、存储历史消息

这里提供一个简单的示例代码,实现了Spring Boot和Vue.js的单聊功能,使用WebSocket进行实时通信,并使用Redis存储历史消息。 后端代码(Spring Boot): 1. 依赖: ```xml <dependencies> <!-- Spring Boot Websocket --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> <!-- Spring Boot Redis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-- JSON --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency> </dependencies> ``` 2. 配置文件: ```yml spring: redis: host: localhost port: 6379 logging: level: org.springframework.web.socket: DEBUG ``` 3. 实体类: ```java public class Message { private String from; private String to; private String content; private Date time; // getters and setters } ``` 4. WebSocket配置: ```java @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { @Autowired private WebSocketHandler webSocketHandler; @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(webSocketHandler, "/chat").setAllowedOrigins("*"); } } ``` 5. WebSocket处理器: ```java @Component public class WebSocketHandler extends TextWebSocketHandler { @Autowired private RedisTemplate<String, Message> redisTemplate; private ObjectMapper objectMapper = new ObjectMapper(); private static final String KEY_PREFIX = "chat:"; @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { // 获取当前用户 String user = (String) session.getAttributes().get("user"); // 订阅Redis频道 redisTemplate.execute(new RedisCallback<Void>() { @Override public Void doInRedis(RedisConnection connection) throws DataAccessException { connection.subscribe(new MessageListener(), KEY_PREFIX + user); return null; } }); // 发送历史消息 List<Message> messages = redisTemplate.opsForList().range(KEY_PREFIX + user, 0, -1); if (messages != null && messages.size() > 0) { for (Message message : messages) { session.sendMessage(new TextMessage(objectMapper.writeValueAsString(message))); } } } @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { // 获取当前用户 String user = (String) session.getAttributes().get("user"); // 解析消息 Message msg = objectMapper.readValue(message.getPayload(), Message.class); msg.setFrom(user); msg.setTime(new Date()); // 存储到Redis redisTemplate.opsForList().rightPush(KEY_PREFIX + msg.getTo(), msg); // 发送给对方 WebSocketSession targetSession = sessions.get(msg.getTo()); if (targetSession != null && targetSession.isOpen()) { targetSession.sendMessage(new TextMessage(objectMapper.writeValueAsString(msg))); } } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception { // 获取当前用户 String user = (String) session.getAttributes().get("user"); // 取消订阅Redis频道 redisTemplate.execute(new RedisCallback<Void>() { @Override public Void doInRedis(RedisConnection connection) throws DataAccessException { connection.unsubscribe(KEY_PREFIX + user); return null; } }); } private Map<String, WebSocketSession> sessions = new ConcurrentHashMap<>(); private class MessageListener implements MessageListenerAdapter { @Override public void onMessage(Message message, byte[] pattern) { WebSocketSession session = sessions.get(message.getTo()); if (session != null && session.isOpen()) { try { session.sendMessage(new TextMessage(objectMapper.writeValueAsString(message))); } catch (Exception e) { e.printStackTrace(); } } } } } ``` 6. 控制器: ```java @RestController @RequestMapping("/api/chat") public class ChatController { @Autowired private RedisTemplate<String, Message> redisTemplate; @PostMapping("/send") public void send(@RequestBody Message message) { // 存储到Redis redisTemplate.opsForList().rightPush("chat:" + message.getFrom(), message); redisTemplate.opsForList().rightPush("chat:" + message.getTo(), message); // 发布消息 redisTemplate.convertAndSend("chat:" + message.getTo(), message); } @GetMapping("/history") public List<Message> history(String user1, String user2) { String key = "chat:" + user1 + ":" + user2; List<Message> messages = redisTemplate.opsForList().range(key, 0, -1); Collections.reverse(messages); return messages; } } ``` 前端代码(Vue.js): 1. 依赖: ```html <script src="/js/vue.min.js"></script> <script src="/js/sockjs.min.js"></script> <script src="/js/stomp.min.js"></script> <script src="/js/lodash.min.js"></script> ``` 2. HTML: ```html <div id="app"> <div> <label>当前用户:</label> <select v-model="currentUser" @change="connect"> <option v-for="user in users" :value="user">{{ user }}</option> </select> </div> <div v-if="connected"> <div> <label>对方用户:</label> <input v-model="otherUser"> </div> <div> <textarea v-model="message"></textarea> <button @click="send">发送</button> </div> <div> <ul> <li v-for="msg in messages">{{ msg.from }} -> {{ msg.to }}: {{ msg.content }}</li> </ul> </div> </div> </div> ``` 3. JavaScript: ```javascript var app = new Vue({ el: '#app', data: { users: ['user1', 'user2', 'user3'], currentUser: 'user1', otherUser: '', message: '', connected: false, messages: [] }, methods: { connect: function () { var self = this; if (self.stompClient != null) { self.stompClient.disconnect(); } var socket = new SockJS('/chat'); self.stompClient = Stomp.over(socket); self.stompClient.connect({}, function () { self.stompClient.subscribe('/user/queue/messages', function (msg) { var message = JSON.parse(msg.body); self.messages.push(message); }); self.connected = true; }, function (error) { console.log(error); }); }, send: function () { var self = this; var message = { from: self.currentUser, to: self.otherUser, content: self.message }; self.stompClient.send('/app/chat/send', {}, JSON.stringify(message)); self.message = ''; }, loadHistory: function () { var self = this; axios.get('/api/chat/history', { params: { user1: self.currentUser, user2: self.otherUser } }).then(function (response) { self.messages = response.data; }).catch(function (error) { console.log(error); }); } }, watch: { otherUser: function (newValue) { var self = this; self.loadHistory(); } } }); ``` 注意事项: 1. Redis的键名使用了前缀“chat:”,以便区分其他数据; 2. 存储历史消息和订阅消息时,使用了当前用户的名称作为频道名称; 3. 在订阅消息时,使用了内部类MessageListener处理接收到的消息,然后发送给对应的WebSocketSession; 4. 在WebSocketSession关闭时,需要取消订阅Redis频道,以免造成资源浪费; 5. 前端使用了STOMP协议进行通信,需要安装sockjs-client和stompjs库; 6. 前端通过WebSocket连接到后端时,需要指定当前用户; 7. 前端通过WebSocket接收到消息时,需要将消息添加到消息列表中; 8. 前端通过REST API加载历史消息时,需要指定当前用户和对方用户。 这是一个基础的示例,具体实现可以根据自己的需求进行调整。

相关推荐

最新推荐

recommend-type

Android开发BLE 串口调试工具,用来和底层进行一些握手协议的调试

【Android】开发BLE 串口调试工具,用来和底层进行一些握手协议的调试。
recommend-type

机械设计自动锁垫片机(sw18可编辑+工程图+BOM)非常好的设计图纸100%好用.zip

机械设计自动锁垫片机(sw18可编辑+工程图+BOM)非常好的设计图纸100%好用.zip
recommend-type

基于Mediapipe的手势识别前端应用可执行程序+说明.zip

基于Mediapipe的手势识别前端应用可执行程序+说明.zip # 项目简介 * 基于AutoHotkey制作的摄像头手势识别软件。能让你的电脑摄像头在识别手势后,执行自定义的电脑操作命令。同时也集成了语音识别功能,可调用Windows自带API实现简单的语音助手功能。 * 手势识别调用了高性能的Mediapipe动态链接库来免部署实现。而电脑自动化操作使用AutoHotkey脚本语言来实现,它能更方便的对电脑进行深度调用和流程自动化处理。 # 使用介绍 * 测试环境:Win10 64位(专业版完整镜像) * **第一次运行 Visual_Gesture_Recognition.exe**时,会提示下载手势识别的**依赖包**。点击**确定**后,跟着提示**点击自动下载**
recommend-type

node-v4.8.0.tar.xz

Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。
recommend-type

python烟花代码.zip

python烟花代码python烟花代码.zip python烟花代码.zippython烟花代码.zippython烟花代码.zippython烟花代码.zippython烟花代码.zippython烟花代码.zippython烟花代码.zippython烟花代码.zippython烟花代码.zippython烟花代码.zippython烟花代码.zippython烟花代码.zippython烟花代码.zippython烟花代码.zippython烟花代码.zippython烟花代码.zippython烟花代码.zippython烟花代码.zippython烟花代码.zippython烟花代码.zippython烟花代码.zippython烟花代码.zippython烟花代码.zippython烟花代码.zippython烟花代码.zippython烟花代码.zippython烟花代码.zippython烟花代码.zippython烟花代码.zippython烟花代码.zippython烟花代码.zippython烟花代码.zippython烟花代码.zip
recommend-type

RTL8188FU-Linux-v5.7.4.2-36687.20200602.tar(20765).gz

REALTEK 8188FTV 8188eus 8188etv linux驱动程序稳定版本, 支持AP,STA 以及AP+STA 共存模式。 稳定支持linux4.0以上内核。
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

Redis验证与连接:安装成功验证技巧

![Redis从入门到精通](https://img-blog.csdnimg.cn/6f39d0a2adc3456b96e804eb45032480.png) # 1. Redis安装与验证** ### 2.2 Redis验证方法 Redis验证可以通过以下方法进行: - **命令行验证:** - 打开终端,输入 `redis-cli` 命令进入 Redis 命令行。 - 输入 `ping` 命令,如果返回 "PONG",则表示 Redis 正在运行。 - **客户端验证:** - 使用 Redis 客户端(如 RedisInsight)连接到 Redis 服务器。
recommend-type

3、自定义一个函数int compareStr(char *p1, char *p2),实现两个字符串的比较。相等返回0,大于返回1,小于返回0;编写主函数main()来调用自定义函数完成测试。

下面是自定义的 `compareStr` 函数的代码实现: ```c #include <stdio.h> int compareStr(char *p1, char *p2) { while (*p1 && *p2 && (*p1 == *p2)) { p1++; p2++; } return (*p1 > *p2) - (*p1 < *p2); } int main() { char str1[100], str2[100]; int result; printf("请输入第一个字符串:");
recommend-type

c++校园超市商品信息管理系统课程设计说明书(含源代码) (2).pdf

校园超市商品信息管理系统课程设计旨在帮助学生深入理解程序设计的基础知识,同时锻炼他们的实际操作能力。通过设计和实现一个校园超市商品信息管理系统,学生掌握了如何利用计算机科学与技术知识解决实际问题的能力。在课程设计过程中,学生需要对超市商品和销售员的关系进行有效管理,使系统功能更全面、实用,从而提高用户体验和便利性。 学生在课程设计过程中展现了积极的学习态度和纪律,没有缺勤情况,演示过程流畅且作品具有很强的使用价值。设计报告完整详细,展现了对问题的深入思考和解决能力。在答辩环节中,学生能够自信地回答问题,展示出扎实的专业知识和逻辑思维能力。教师对学生的表现予以肯定,认为学生在课程设计中表现出色,值得称赞。 整个课程设计过程包括平时成绩、报告成绩和演示与答辩成绩三个部分,其中平时表现占比20%,报告成绩占比40%,演示与答辩成绩占比40%。通过这三个部分的综合评定,最终为学生总成绩提供参考。总评分以百分制计算,全面评估学生在课程设计中的各项表现,最终为学生提供综合评价和反馈意见。 通过校园超市商品信息管理系统课程设计,学生不仅提升了对程序设计基础知识的理解与应用能力,同时也增强了团队协作和沟通能力。这一过程旨在培养学生综合运用技术解决问题的能力,为其未来的专业发展打下坚实基础。学生在进行校园超市商品信息管理系统课程设计过程中,不仅获得了理论知识的提升,同时也锻炼了实践能力和创新思维,为其未来的职业发展奠定了坚实基础。 校园超市商品信息管理系统课程设计的目的在于促进学生对程序设计基础知识的深入理解与掌握,同时培养学生解决实际问题的能力。通过对系统功能和用户需求的全面考量,学生设计了一个实用、高效的校园超市商品信息管理系统,为用户提供了更便捷、更高效的管理和使用体验。 综上所述,校园超市商品信息管理系统课程设计是一项旨在提升学生综合能力和实践技能的重要教学活动。通过此次设计,学生不仅深化了对程序设计基础知识的理解,还培养了解决实际问题的能力和团队合作精神。这一过程将为学生未来的专业发展提供坚实基础,使其在实际工作中能够胜任更多挑战。