您的位置:首页 > 汽车 > 新车 > 门户网站建设方案费用_东莞最新一例阳性_网站关键词推广_怎么建立自己的企业网站

门户网站建设方案费用_东莞最新一例阳性_网站关键词推广_怎么建立自己的企业网站

2025/4/29 19:40:51 来源:https://blog.csdn.net/gaosw0521/article/details/147450007  浏览:    关键词:门户网站建设方案费用_东莞最新一例阳性_网站关键词推广_怎么建立自己的企业网站
门户网站建设方案费用_东莞最新一例阳性_网站关键词推广_怎么建立自己的企业网站

在技术派平台中,实现了文章被点赞或评论后,在右上角实时弹出消息提醒的功能。相较于之前仅有的消息通知红色标识,这种实时通知在交互体验上有显著提升。本文将详细介绍如何借助WebSocket实现消息的实时通知。

1 基础知识点

1.1 相关概念

  1. WebSocket:WebSocket是一种在单个TCP连接上进行全双工通信的协议,能使客户端和服务器实时地双向传输数据,无需频繁建立和关闭连接,可提高数据传输的效率和性能。
  2. STOMPSimple Text Oriented Messaging Protocol,即简单文本定向消息协议,是在HTTP之上实现的简单灵活的消息传递协议,定义了一套简单的命令和帧格式用于客户端和服务器间的消息传递,可实现双向通讯。需注意,STOMP协议属于WebSocket的子协议。

1.2 WebSocket整合STOMP

WebSocket整合STOMP协议实现双向通讯的主要步骤如下:

  1. 建立WebSocket连接:客户端通过JavaScript的WebSocket API与服务器建立连接。
  2. 发送STOMP帧:连接建立后,客户端和服务器通过发送STOMP帧进行通信,STOMP帧是STOMP协议的基本单位,定义了订阅、发布等消息操作。
  3. 处理STOMP帧:服务器收到STOMP帧后,根据帧类型进行相应处理,如收到SUBSCRIBE帧为客户端创建订阅,收到SEND帧将消息发送到指定目的地。
  4. 关闭WebSocket连接:通信完成后,通过调用WebSocket API的close方法关闭连接。
    在这里插入图片描述

1.3 SpringBoot整合STOMP流程

SpringBoot对WebSocket提供了友好封装,便于搭建基于STOMP协议的WebSocket应用工程。其基本工作流程如下:

  1. 步骤1:初始化

    • 服务端:定义接收WebSocket连接的端点EndPoint;配置消息代理Broker,用于前端订阅,后端向Broker写入消息后,订阅该Broker的前端会收到相应消息;配置路由转发规则,将用户信息转发给相应处理器(类似RequestMappingHandlerMapping@RequestMapping注解,WebSocket中使用Destination + @MessageMapping)。
    • 客户端:与EndPoint建立连接;订阅Broker并注册消息回调。
      在这里插入图片描述
  2. 步骤2:通讯

    • 服务端:主动向Broker写入消息,使用simpMessagingTemplate;消息应答使用@SendTo注解。
    • 客户端:发送消息调用send(xxxx)方法;消息应答触发订阅的回调函数。
      在这里插入图片描述

2 WebSocket集成

相关示例demo可在https://github.com/liuyueyi/spring-boot-demo/tree/master/spring-boot/203-websocket获取。

2.1 依赖配置

在Spring Boot应用的pom.xml配置文件中,引入WebSocket的核心依赖。

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

2.2 WebSocket配置

后端通过实现配置类StompConfiguration来定义相关信息:

@Configuration
@EnableWebSocketMessageBroker
public class StompConfiguration implements WebSocketMessageBrokerConfigurer {// 配置消息代理@Overridepublic void configureMessageBroker(MessageBrokerRegistry registry) {registry.enableSimpleBroker("/topic"); // 客户端订阅地址前缀registry.setApplicationDestinationPrefixes("/app"); // 服务端接收地址前缀}// 注册STOMP端点@Overridepublic void registerStompEndpoints(StompEndpointRegistry registry) {registry.addEndpoint("/ws/hello").withSockJS(); // 客户端连接端点}
}
  1. 定义端点:使用registerStompEndpoints()方法。
  2. 定义客户端与服务端通讯信息:使用configureMessageBroker()方法,配置消息代理registry.enableSimpleBroker,配置消息转发registry.setApplicationDestinationPrefixes(转发前缀可为多个)。

配置完成后,客户端的相关路径为:建立连接路径是/ws/hello;订阅消息路径是/topic/xxx(由@SendTo的路径确定);接收前端消息路径是/app/xxx(由@MessageMapping中的路径补齐)。

2.3 消息接收应答

实现简单消息应答,接收客户端向/app/hello发送的消息,将结果写回到/topic/hello对应的Broker,订阅该Broker的客户端会收到应答消息。

@Controller
public class HelloController {// 处理/app/hello路径的STOMP消息@MessageMapping("/hello")@SendTo("/topic/hello") // 将返回结果广播到指定主题public String greeting(String message) {return "[" + LocalDateTime.now() + "]: " + message;}
}

同时,编写定时器,由后端定时向/topic/hello这个Broker中写入消息,模拟后台主动下发消息场景。

@Autowired
private SimpMessagingTemplate simpMessagingTemplate;// 定时推送示例(当前被注释)
@Scheduled(cron = "0/10 * * * * ?")
public void autoPush() {simpMessagingTemplate.convertAndSend("/topic/hello", "系统自动消息");
}

2.4 执行流程解析

var stompClient = null;function setConnected(connected) {$("#connect").prop("disabled", connected);$("#disconnect").prop("disabled", !connected);if (connected) {$("#conversation").show();}else {$("#conversation").hide();}$("#greetings").html("");
}function connect() {var socket = new SockJS('/ws/hello');stompClient = Stomp.over(socket);stompClient.connect({}, function (frame) {setConnected(true);console.log('Connected: ' + frame);stompClient.subscribe('/topic/hello', function (greeting) {console.log("resp: ", greeting.body)showGreeting(greeting.body);});});
}function disconnect() {if (stompClient !== null) {stompClient.disconnect();}setConnected(false);console.log("Disconnected");
}function sendName() {stompClient.send("/app/hello", {}, JSON.stringify({'name': $("#name").val()}));
}function showGreeting(message) {$("#greetings").append("<tr><td>" + message + "</td></tr>");
}$(function () {$("form").on('submit', function (e) {e.preventDefault();});$("#connect").click(function () {connect();});$("#disconnect").click(function () {disconnect();});$("#send").click(function () {sendName();});
});

核心js逻辑实现WebSocket连接建立与通讯:

  1. 建立连接connect():通过new SockJS('/ws/hello')与后端端点建立连接;连接成功后,使用stompClient.subscribe('/topic/hello', 消息应答回调)订阅Broker并接收消息回传。
  2. 发送消息:调用stompClient.send("/app/hello", xxx)方法。
  3. 断开连接:调用stompClient.disconnect()方法。

2.5 效果演示

完成基于Spring Boot整合WebSocket与STOMP协议的示例应用搭建后,启动应用,可看到前端建立连接后向后端发送信息并接收后端广播消息的过程,多个客户端订阅同一Broker时,能收到后端发送的消息。
在这里插入图片描述

3 技术派基于WebSocket的消息通知

3.1 消息推送配置

WsChatConfig 是一个 Spring 配置类,其主要功能是配置基于 STOMP(Simple Text Oriented Messaging Protocol)协议的 WebSocket 通信。下面按照代码结构详细说明其逻辑:

  1. 类定义与注解
@Slf4j
@Configuration
@EnableWebSocketMessageBroker
public class WsChatConfig implements WebSocketMessageBrokerConfigurer {
  • @Slf4j:Lombok 提供的注解,会自动为该类生成一个日志记录器 log,方便日志输出。
  • @Configuration:Spring 注解,表明该类是一个配置类,Spring 容器会扫描并加载其中定义的 Bean。
  • @EnableWebSocketMessageBroker:启用基于消息代理的 WebSocket 支持,允许应用使用 STOMP 协议进行消息传递。
  • implements WebSocketMessageBrokerConfigurer:实现该接口,需要重写其中的方法来定制 WebSocket 消息代理的配置。
  1. 配置消息代理
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {config.enableSimpleBroker("/chat");config.setApplicationDestinationPrefixes("/app");
}
  • config.enableSimpleBroker("/chat"):启用一个简单的基于内存的消息代理,客户端订阅以 /chat 开头的目的地后,就可以接收从服务端广播的消息。
  • config.setApplicationDestinationPrefixes("/app"):设置应用程序的目标前缀,以 /app 开头的消息会被路由到带有 @MessageMapping 注解的控制器方法进行处理。
  1. 注册 STOMP 端点
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {registry.addEndpoint("/gpt/{id}/{aiType}").setHandshakeHandler(new AuthHandshakeHandler()).addInterceptors(new AuthHandshakeInterceptor()).setAllowedOriginPatterns("*");
}
  • registry.addEndpoint("/gpt/{id}/{aiType}"):注册一个 WebSocket 端点,客户端可以通过这个端点连接到服务端。{id}{aiType} 是路径变量,可用于标识不同的用户和 AI 类型。
  • .setHandshakeHandler(new AuthHandshakeHandler()):设置自定义的握手处理器,用于在 WebSocket 握手阶段进行身份验证等操作。
  • .addInterceptors(new AuthHandshakeInterceptor()):添加自定义的握手拦截器,进一步处理握手过程中的逻辑。
  • .setAllowedOriginPatterns("*"):允许所有来源的跨域请求,确保不同域名的客户端都能连接到该端点。
  1. 配置消息通道拦截器
@Override
public void configureClientInboundChannel(ChannelRegistration registration) {registration.interceptors(channelInInterceptor());
}@Override
public void configureClientOutboundChannel(ChannelRegistration registration) {registration.interceptors(channelOutInterceptor());
}
  • configureClientInboundChannel:配置客户端发送到服务端的消息通道,添加入站拦截器 channelInInterceptor(),用于处理客户端发来的消息。
  • configureClientOutboundChannel:配置服务端发送到客户端的消息通道,添加出站拦截器 channelOutInterceptor(),用于处理服务端返回给客户端的消息。
  1. 定义 Bean
@Bean
public HandshakeHandler handshakeHandler() {return new AuthHandshakeHandler();
}@Bean
public HttpSessionHandshakeInterceptor handshakeInterceptor() {return new AuthHandshakeInterceptor();
}@Bean
public ChannelInterceptor channelInInterceptor() {return new AuthInChannelInterceptor();
}@Bean
public ChannelInterceptor channelOutInterceptor() {return new AuthOutChannelInterceptor();
}
  • 使用 @Bean 注解将自定义的握手处理器、握手拦截器、入站拦截器和出站拦截器注册为 Spring Bean,方便 Spring 容器进行管理和使用。

综上所述,WsChatConfig 类通过实现 WebSocketMessageBrokerConfigurer 接口,完成了 WebSocket 端点的注册、消息代理的配置以及消息通道拦截器的设置,从而实现了基于 STOMP 协议的 WebSocket 通信功能,同时加入了身份验证等安全机制。

3.2 身份鉴权拦截器

AuthHandshakeInterceptor 类继承自 HttpSessionHandshakeInterceptor,主要作用是在 WebSocket 握手阶段进行用户身份验证和识别。下面详细解释其代码逻辑:

  1. 类定义和继承
public class AuthHandshakeInterceptor extends HttpSessionHandshakeInterceptor {

这行代码定义了 AuthHandshakeInterceptor 类,并继承自 HttpSessionHandshakeInterceptorHttpSessionHandshakeInterceptor 是 Spring 提供的用于在 WebSocket 握手过程中处理 HTTP 会话的拦截器,继承它可以利用其已有的功能,同时自定义握手逻辑。

  1. 握手前的身份验证 (beforeHandshake 方法)
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {log.info("准备开始握手了!");String session = SessionUtil.findCookieByName(request, LoginService.SESSION_KEY);ReqInfoContext.ReqInfo reqInfo = new ReqInfoContext.ReqInfo();SpringUtil.getBean(GlobalInitService.class).initLoginUser(session, reqInfo);if (reqInfo.getUser() == null) {log.info("websocket 握手失败,请登录之后再试");return false;}// 将用户信息写入到属性中attributes.put(MdcUtil.TRACE_ID_KEY, SelfTraceIdGenerator.generate());attributes.put(LoginService.SESSION_KEY, reqInfo);attributes.put(WsAnswerHelper.AI_SOURCE_PARAM, initAiSource(request.getURI().getPath()));return true;
}
  • 日志记录:使用 log.info 记录开始握手的信息。
  • 获取会话信息:通过 SessionUtil.findCookieByName 方法从请求中获取名为 LoginService.SESSION_KEYCookie 值。
  • 初始化用户信息:创建 ReqInfoContext.ReqInfo 对象,并调用 GlobalInitServiceinitLoginUser 方法,根据会话信息初始化用户信息。
  • 身份验证:检查 reqInfo 中的用户信息是否为空,如果为空则记录握手失败的日志并返回 false,表示握手失败。
  • 设置属性:如果身份验证通过,将生成的跟踪 ID、用户请求信息和 AI 来源信息添加到 attributes 中,这些信息将在后续的 WebSocket 通信中使用。最后返回 true,表示握手成功。
  1. 初始化 AI 来源 (initAiSource 方法)
private String initAiSource(String path) {int index = path.lastIndexOf("/");return path.substring(index + 1);
}

该方法从请求的 URI 路径中提取 AI 来源信息。通过查找最后一个 / 的位置,然后截取该位置之后的字符串作为 AI 来源。

  1. 握手后的处理 (afterHandshake 方法)
@Override
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception ex) {log.info("握手成功了!!!");super.afterHandshake(request, response, wsHandler, ex);
}

在握手成功后,使用 log.info 记录握手成功的日志,并调用父类的 afterHandshake 方法完成后续处理。

综上所述,AuthHandshakeInterceptor 类在 WebSocket 握手过程中进行用户身份验证,确保只有登录用户可以建立 WebSocket 连接,并在握手前后记录日志和处理相关信息。

3.3 握手处理器

AuthHandshakeHandler 类继承自 DefaultHandshakeHandler,主要用于在 WebSocket 握手过程中确定连接的用户身份。下面详细解释其代码逻辑:

  1. 类定义和注解
@Slf4j
public class AuthHandshakeHandler extends DefaultHandshakeHandler {
  • @Slf4j:Lombok 注解,用于自动生成日志记录器 log,方便在类中记录日志。
  • extends DefaultHandshakeHandler:继承 DefaultHandshakeHandler 类,该类是 Spring 提供的默认握手处理器,AuthHandshakeHandler 可以重写其方法来实现自定义的握手逻辑。
  1. 重写 determineUser 方法
@Override
protected Principal determineUser(ServerHttpRequest request, WebSocketHandler wsHandler, Map<String, Object> attributes) {// case1: 根据cookie来识别用户,即可以实现所有用户连相同的ws地址,然后再 AuthHandshakeChannelInterceptor 中进行destination的转发ReqInfoContext.ReqInfo reqInfo = (ReqInfoContext.ReqInfo) attributes.get(LoginService.SESSION_KEY);if (reqInfo != null) {return reqInfo;}// case2: 根据路径来区分用户// 获取例如 ws://localhost/gpt/id 订阅地址中的最后一个用户 id 参数作为用户的标识, 为实现发送信息给指定用户做准备String uri = request.getURI().toString();String uid = uri.substring(uri.lastIndexOf("/") + 1);log.info("{} -> {}", uri, uid);return () -> uid;
}
  • determineUser 方法是 DefaultHandshakeHandler 中的一个受保护方法,用于在握手过程中确定连接的用户身份。重写该方法可以实现自定义的用户身份识别逻辑。
  • 身份识别方式一:通过 Cookie 识别
    • attributes 中获取 LoginService.SESSION_KEY 对应的值,将其转换为 ReqInfoContext.ReqInfo 对象。
    • 如果 reqInfo 不为空,则将其作为 Principal 返回,表示用户身份已通过 Cookie 识别。
  • 身份识别方式二:通过路径识别
    • 如果通过 Cookie 未能识别用户身份,则从请求的 URI 中提取最后一个 / 之后的部分作为用户 ID。
    • 使用 Lambda 表达式创建一个 Principal 对象,其 getName() 方法返回提取的用户 ID。
    • 记录请求 URI 和提取的用户 ID 的日志信息。

综上所述,AuthHandshakeHandler 类在 WebSocket 握手过程中,通过两种方式确定连接的用户身份,确保后续的消息可以准确地发送给指定用户。

3.4 消息发送与处理

WsAnswerHelper 是一个 Spring 组件,主要职责是借助 WebSocket 向用户实时推送聊天相关消息,在技术派项目里实现消息实时推送功能。下面对其代码逻辑展开详细说明:

3.4.1 消息发送方法

  1. sendMsgToUser(String session, String question)
public void sendMsgToUser(String session, String question) {ChatRecordsVo res = chatFacade.autoChat(question, vo -> response(session, vo));log.info("AI直接返回:{}", res);
}
  • 调用 chatFacade.autoChat 方法发起自动聊天,传入用户提问 question 以及一个回调函数。
  • 回调函数 vo -> response(session, vo) 会在获取到聊天结果后,调用 response 方法把结果推送给指定用户。
  • 记录 AI 返回结果的日志。
  1. sendMsgToUser(AISourceEnum ai, String session, String question)
public void sendMsgToUser(AISourceEnum ai, String session, String question) {if (ai == null) {// 自动选择AI类型sendMsgToUser(session, question);} else {ChatRecordsVo res = chatFacade.autoChat(ai, question, vo -> response(session, vo));log.info("AI直接返回:{}", res);}
}
  • 若传入的 ai 为 null,则调用 sendMsgToUser(session, question) 方法自动选择 AI 类型进行聊天。
  • 若 ai 不为 null,则调用 chatFacade.autoChat 方法,指定 AI 类型进行聊天,并将结果推送给用户,同时记录日志。
  1. sendMsgHistoryToUser(String session, AISourceEnum ai)
 public void sendMsgHistoryToUser(String session, AISourceEnum ai) {ChatRecordsVo vo = chatFacade.history(ai);response(session, vo);}
  • 调用 chatFacade.history 方法获取指定 AI 类型的聊天历史记录。
  • 调用 response 方法将聊天历史记录推送给指定用户。

3.4.2 消息推送方法

    /*** 将返回结果推送给用户** @param session* @param response*/public void response(String session, ChatRecordsVo response) {// convertAndSendToUser 方法可以发送信给给指定用户,// 底层会自动将第二个参数目的地址 /chat/rsp 拼接为// /user/username/chat/rsp,其中第二个参数 username 即为这里的第一个参数 session// username 也是AuthHandshakeHandler中配置的 Principal 用户识别标志simpMessagingTemplate.convertAndSendToUser(session, "/chat/rsp", response);}
  • 借助 SimpMessagingTemplate 的 convertAndSendToUser 方法,把聊天结果 response 推送给指定用户 session。
  • 目标地址 /chat/rsp 会自动拼接成 /user/username/chat/rsp,这里的 username 就是 session。

3.4.3 业务逻辑执行方法

    public void execute(Map<String, Object> attributes, Runnable func) {try {ReqInfoContext.ReqInfo reqInfo = (ReqInfoContext.ReqInfo) attributes.get(LoginService.SESSION_KEY);ReqInfoContext.addReqInfo(reqInfo);String traceId = (String) attributes.get(MdcUtil.TRACE_ID_KEY);MdcUtil.add(MdcUtil.TRACE_ID_KEY, traceId);// 执行具体的业务逻辑func.run();} finally {ReqInfoContext.clear();MdcUtil.clear();}}
  • attributes 里获取用户请求信息 reqInfo 和跟踪 ID traceId,并分别添加到 ReqInfoContextMdcUtil 中。
  • 执行传入的业务逻辑 func.run()
  • 无论业务逻辑是否执行成功,最后都要清除 ReqInfoContextMdcUtil 中的信息。

综上所述,WsAnswerHelper 类整合了聊天服务和 WebSocket 消息推送功能,实现了消息的实时发送和推送,同时对请求信息和跟踪 ID 进行管理。

3.5 前端页面集成

在前端页面 paicoding-ui/src/main/resources/templates/views/chat-home/index.html中,可以使用 JavaScript 代码来连接 WebSocket 并接收消息。

3.5.1 连接 WebSocket

<script th:inline="javascript">// ... 其他代码 ...const isLogin = [[${global.isLogin}]], user = [[${global.user}]];let stompClient = null;$(function () {if (isLogin) {initWs();} else {console.log("请先登录");}});function initWs() {let protocol = window.location.protocol.replace("http", "ws");let host = window.location.host;let aiType = $('#chat-type').val();const session = getCookie("f-session");let socket = new WebSocket(`${protocol}//${host}/gpt/${session}/${aiType}`);stompClient = Stomp.over(socket);stompClient.connect({}, function (frame) {console.log('ws连接成功: ' + frame);// 其他操作...});// 关闭链接socket.onclose = disconnect;}// ... 其他代码 ...
</script>
  • 登录状态判断:借助 Thymeleaf 模板引擎获取后端传递的登录状态 isLogin 和用户信息 user。页面加载完成后,若用户已登录,则调用 initWs方法来初始化 WebSocket 连接;反之,在控制台输出提示信息。
  • 构建 WebSocket 地址initWs 方法先把当前页面的协议从 http 替换成 ws,接着获取当前页面的主机名,再获取下拉框选中的 AI 类型 aiType 以及用户的会话 session,最后构建出完整的 WebSocket 连接地址。
  • 创建 WebSocket 连接:使用 new WebSocket 创建 WebSocket 连接,再用 Stomp.over 方法将其包装成基于 STOMP 协议的客户端。
  • 连接服务器:调用 stompClient.connect 方法连接服务器,连接成功后会执行回调函数,在控制台输出连接成功信息。
  • 处理关闭事件:为 WebSocket 的 onclose 事件绑定 disconnect 方法,当连接关闭时会触发该方法。

3.5.2 订阅消息

<script th:inline="javascript">// ... 其他代码 ...function initWs() {// ... 其他代码 ...stompClient.connect({}, function (frame) {console.log('ws连接成功: ' + frame);// 订阅消息stompClient.subscribe(`/user/chat/rsp`, function (message) {// 解析 JSON 字符串console.log("rsp:", message);let res = JSON.parse(message.body);console.log("res:", res);// 记录聊天次数$("#chatCnt").html(` ${res.usedCnt}/${res.maxCnt} `);const data = res.records;// 移除 loading 元素$(".home_chat-message-actions__loading").remove();if (data.length > 1) {// 返回历史全部信息chatContent.html('');for (let i = data.length - 1; i >= 0; i--) {if (data[i].question) {addClientMsg(data[i].question, false);}if (i == 0) {addSplit();}appendServerMessage(data[i]);}} else {appendServerMessage(data[0]);}// 除流式持续返回场景,恢复按钮状态if(data[data.length - 1].answerType != 'STREAM') {sendBtn.removeAttr("disabled");}});});// ... 其他代码 ...}// ... 其他代码 ...
</script>
  • 订阅目的地:在 stompClient.connect 的回调函数里,调用 stompClient.subscribe 方法订阅 /user/chat/rsp 目的地,该目的地是服务器推送消息的目标地址。
  • 处理接收到的消息:当服务器向该目的地推送消息时,会触发回调函数。在回调函数中,先将接收到的消息体解析成 JSON 对象,然后更新页面上的聊天次数,移除加载中的提示元素,根据消息数据的长度不同,采用不同的方式将消息添加到聊天界面,最后根据消息类型恢复发送按钮的状态。

3.5.3 发送消息

<script th:inline="javascript">// ... 其他代码 ...function doSend() {const qa = inputField.val();if (qa.length > 512) {toastr.info("提问长度请不要超过512字符哦~");return;}stompClient.send("/app/chat/" + session, {'s-uid': session}, qa);inputField.val("");addClientMsg(qa.replace(/\n/g, "<br/>"), true);sendBtn.attr("disabled", true);}sendBtn.click(function () {if (stompClient == null) {initWs();} else {if (inputField.val() === "") {inputField.focus();} else {doSend();}}});inputField.keydown(function (e) {if (e.keyCode === 13) {sendBtn.click();e.preventDefault();}});// ... 其他代码 ...
</script>
  • doSend 方法:获取输入框中的内容,若内容长度超过 512 字符,则给出提示并返回;否则,调用 stompClient.send 方法将消息发送到 /app/chat/ 加上会话 ID 的地址,同时传递自定义头信息 {'s-uid': session}。发送消息后,清空输入框,在聊天界面添加用户消息,并禁用发送按钮。
  • 按钮点击事件:为发送按钮绑定点击事件,若 stompClient 为空,则调用 initWs 方法初始化连接;否则,若输入框内容为空,则将焦点聚焦到输入框,反之调用 doSend 方法发送消息。
  • 回车键事件:为输入框绑定按键事件,当按下回车键时,触发发送按钮的点击事件,并阻止回车键的默认行为。

综上所述,前端代码通过上述步骤实现了 WebSocket 的连接、消息的订阅和发送功能,从而与服务器进行实时通信。

4 小结

本文聚焦WebSocket的应用,涵盖其基础概念、Spring整合STOMP的流程图、Spring Boot应用集成WebSocket实现双向通信,以及技术派中基于WebSocket实现消息推送的全过程。

5 参考链接

  1. 技术派整合WebSocket实现消息实时推送
  2. 项目仓库(GitHub)

版权声明:

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

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