欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 建筑 > 【开源宝藏】Jeepay VUE和React构建WebSocket通用模板

【开源宝藏】Jeepay VUE和React构建WebSocket通用模板

2025/1/19 3:55:11 来源:https://blog.csdn.net/qq_41520636/article/details/145210416  浏览:    关键词:【开源宝藏】Jeepay VUE和React构建WebSocket通用模板

WebSocket 服务实现:Spring Boot 示例

在现代应用程序中,WebSocket 是实现双向实时通信的重要技术。本文将介绍如何使用 Spring Boot 创建一个简单的 WebSocket 服务,并提供相关的代码示例。

1. WebSocket 简介

WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。与传统的 HTTP 请求-响应模式相比,WebSocket 允许服务器主动向客户端推送消息,适用于实时应用,如在线聊天、实时通知和游戏等。

2. 项目结构

在开始之前,确保你的项目中包含必要的依赖。在 pom.xml 中添加以下依赖:

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

3. WebSocket 配置类

为了启用 WebSocket 支持,我们需要创建一个配置类 WebSocketConfig,如下所示:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;/*** 开启WebSocket支持* * @author terrfly* @site https://www.jeequan.com* @date 2021/6/22 12:57*/
@Configuration
public class WebSocketConfig {@Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter();}
}

3.1 配置类解析

  • @Configuration: 表示该类是一个配置类,Spring 会在启动时加载它。
  • ServerEndpointExporter: 这个 Bean 会自动注册所有带有 @ServerEndpoint 注解的 WebSocket 端点。

4. WebSocket 服务类

以下是一个简单的 WebSocket 服务类 WsChannelUserIdServer 的实现。该类负责处理客户端的连接、消息接收和发送。

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.io.IOException;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;@ServerEndpoint("/api/anon/ws/channelUserId/{appId}/{cid}")
@Component
public class WsChannelUserIdServer {private final static Logger logger = LoggerFactory.getLogger(WsChannelUserIdServer.class);private static int onlineClientSize = 0;private static Map<String, Set<WsChannelUserIdServer>> wsAppIdMap = new ConcurrentHashMap<>();private Session session;private String cid = "";private String appId = "";@OnOpenpublic void onOpen(Session session, @PathParam("appId") String appId, @PathParam("cid") String cid) {try {this.cid = cid;this.appId = appId;this.session = session;Set<WsChannelUserIdServer> wsServerSet = wsAppIdMap.get(appId);if (wsServerSet == null) {wsServerSet = new CopyOnWriteArraySet<>();}wsServerSet.add(this);wsAppIdMap.put(appId, wsServerSet);addOnlineCount();logger.info("cid[{}], appId[{}] 连接开启监听!当前在线人数为 {}", cid, appId, onlineClientSize);} catch (Exception e) {logger.error("ws监听异常 cid[{}], appId[{}]", cid, appId, e);}}@OnClosepublic void onClose() {Set<WsChannelUserIdServer> wsSet = wsAppIdMap.get(this.appId);wsSet.remove(this);if (wsSet.isEmpty()) {wsAppIdMap.remove(this.appId);}subOnlineCount();logger.info("cid[{}], appId[{}] 连接关闭!当前在线人数为 {}", cid, appId, onlineClientSize);}@OnErrorpublic void onError(Session session, Throwable error) {logger.error("ws发生错误", error);}public void sendMessage(String message) throws IOException {this.session.getBasicRemote().sendText(message);}public static void sendMsgByAppAndCid(String appId, String cid, String msg) {try {logger.info("推送ws消息到浏览器, appId={}, cid={}, msg={}", appId, cid, msg);Set<WsChannelUserIdServer> wsSet = wsAppIdMap.get(appId);if (wsSet == null || wsSet.isEmpty()) {logger.info("appId[{}] 无ws监听客户端", appId);return;}for (WsChannelUserIdServer item : wsSet) {if (!cid.equals(item.cid)) {continue;}try {item.sendMessage(msg);} catch (Exception e) {logger.info("推送设备消息时异常,appId={}, cid={}", appId, item.cid, e);}}} catch (Exception e) {logger.info("推送消息时异常,appId={}", appId, e);}}public static synchronized int getOnlineClientSize() {return onlineClientSize;}public static synchronized void addOnlineCount() {onlineClientSize++;}public static synchronized void subOnlineCount() {onlineClientSize--;}
}

5. 代码解析

5.1 连接管理

  • @OnOpen: 当客户端连接成功时调用此方法。可以在此方法中获取客户端的 appIdcid,并将当前连接的会话存储到 wsAppIdMap 中。
  • @OnClose: 当客户端连接关闭时调用此方法,从 wsAppIdMap 中移除该连接。
  • @OnError: 处理连接错误。

5.2 消息发送

  • sendMessage(String message): 通过当前会话向客户端发送消息。
  • sendMsgByAppAndCid(String appId, String cid, String msg): 根据 appIdcid 向特定客户端推送消息。

5.3 在线人数管理

使用 onlineClientSize 变量记录当前在线的客户端数量,并提供相应的增减方法。

好的!下面我将为你提供一个简单的前端实现示例,使用 Vue.jsReact 来连接我们之前创建的 WebSocket 服务。这样,你可以看到如何在前端与后端进行实时通信。

6. Vue.js 前端实现

6.1 安装 Vue.js

如果你还没有创建 Vue 项目,可以使用 Vue CLI 创建一个新的项目:

npm install -g @vue/cli
vue create websocket-demo
cd websocket-demo

6.2 创建 WebSocket 组件

src/components 目录下创建一个名为 WebSocketComponent.vue 的文件,并添加以下代码:

<template><div><h1>WebSocket Demo</h1><input v-model="message" placeholder="Type a message" /><button @click="sendMessage">Send</button><div><h2>Messages:</h2><ul><li v-for="(msg, index) in messages" :key="index">{{ msg }}</li></ul></div></div>
</template><script>
export default {data() {return {socket: null,message: '',messages: [],appId: 'yourAppId', // 替换为你的 appIdcid: 'yourClientId'  // 替换为你的客户端自定义ID};},created() {this.connect();},methods: {connect() {this.socket = new WebSocket(`ws://localhost:8080/api/anon/ws/channelUserId/${this.appId}/${this.cid}`);this.socket.onopen = () => {console.log('WebSocket connection established.');};this.socket.onmessage = (event) => {const data = JSON.parse(event.data);this.messages.push(data.message);};this.socket.onclose = () => {console.log('WebSocket connection closed.');};this.socket.onerror = (error) => {console.error('WebSocket error:', error);};},sendMessage() {if (this.socket && this.socket.readyState === WebSocket.OPEN) {this.socket.send(JSON.stringify({ message: this.message }));this.message = ''; // 清空输入框} else {console.error('WebSocket is not open.');}}}
};
</script><style scoped>
/* 添加样式 */
</style>

6.3 使用组件

src/App.vue 中使用这个组件:

<template><div id="app"><WebSocketComponent /></div>
</template><script>
import WebSocketComponent from './components/WebSocketComponent.vue';export default {components: {WebSocketComponent}
};
</script><style>
/* 添加样式 */
</style>

6.4 运行 Vue 应用

在项目根目录下运行以下命令启动 Vue 应用:

npm run serve

7. React 前端实现

7.1 安装 React

如果你还没有创建 React 项目,可以使用 Create React App 创建一个新的项目:

npx create-react-app websocket-demo
cd websocket-demo

7.2 创建 WebSocket 组件

src 目录下创建一个名为 WebSocketComponent.js 的文件,并添加以下代码:

import React, { useEffect, useState } from 'react';const WebSocketComponent = () => {const [socket, setSocket] = useState(null);const [message, setMessage] = useState('');const [messages, setMessages] = useState([]);const appId = 'yourAppId'; // 替换为你的 appIdconst cid = 'yourClientId'; // 替换为你的客户端自定义IDuseEffect(() => {const ws = new WebSocket(`ws://localhost:8080/api/anon/ws/channelUserId/${appId}/${cid}`);setSocket(ws);ws.onopen = () => {console.log('WebSocket connection established.');};ws.onmessage = (event) => {const data = JSON.parse(event.data);setMessages((prevMessages) => [...prevMessages, data.message]);};ws.onclose = () => {console.log('WebSocket connection closed.');};ws.onerror = (error) => {console.error('WebSocket error:', error);};return () => {ws.close();};}, [appId, cid]);const sendMessage = () => {if (socket && socket.readyState === WebSocket.OPEN) {socket.send(JSON.stringify({ message }));setMessage(''); // 清空输入框} else {console.error('WebSocket is not open.');}};return (<div><h1>WebSocket Demo</h1><inputvalue={message}onChange={(e) => setMessage(e.target.value)}placeholder="Type a message"/><button onClick={sendMessage}>Send</button><div><h2>Messages:</h2><ul>{messages.map((msg, index) => (<li key={index}>{msg}</li>))}</ul></div></div>);
};export default WebSocketComponent;

7.3 使用组件

src/App.js 中使用这个组件:

import React from 'react';
import WebSocketComponent from './WebSocketComponent';function App() {return (<div className="App"><WebSocketComponent /></div>);
}export default App;

7.4 运行 React 应用

在项目根目录下运行以下命令启动 React 应用:

npm start

8. 总结

通过以上步骤,我们实现了一个简单的 WebSocket 前端示例,分别使用了 Vue.js 和 React。用户可以通过输入框发送消息,接收来自 WebSocket 服务器的消息。

8.1 注意事项

  • 确保 WebSocket 服务器正在运行,并且前端应用能够访问到它。
  • 替换 yourAppIdyourClientId 为实际的应用 ID 和客户端 ID。

希望这能帮助你更好地理解如何在前端实现 WebSocket 通信!如有任何问题,请随时询问。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com