您的位置:首页 > 科技 > 能源 > Java 使用WebScoket实现消息实时推送

Java 使用WebScoket实现消息实时推送

2024/10/6 1:42:26 来源:https://blog.csdn.net/qq_44217121/article/details/141066850  浏览:    关键词:Java 使用WebScoket实现消息实时推送

参考链接:(java)websocket服务的两种实现方式_java websocket 服务端-CSDN博客

SpringBoot2.0集成WebSocket,实现后台向前端推送信息_springboot集成websocket-CSDN博客

刚接触java如何引入包不太懂,请参考上面的链接。我是直接在pom里面的dependencies标签里加的下面代码:

       <dependency><groupId>cn.control.cp</groupId><artifactId>production-spring-boot-starter-websocket</artifactId></dependency>

后台服务类(特别注意,当一直返回200的话记得找到设置拦截的地方设置:
//httpSecurity.antMatchers("/websocket/**","/ws/**").permitAll()//使WebScoket不会被拦截

):

package cn.control.cp.onway.WebScoket;import cn.hutool.json.JSONUtil;
import com.alibaba.excel.util.StringUtils;
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;@Component
@Slf4j
@ServerEndpoint(value = "/websocket/{userId}")  // 接口路径 ws://localhost:48082/webSocket/userId;
// 注意httpSecurity设置匿名不验证
//httpSecurity.antMatchers("/websocket/**","/ws/**").permitAll()//使WebScoket不会被拦截
public class WebsocketServer {/**静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。*/private static int onlineCount = 0;/**concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。*/private static ConcurrentHashMap<String,WebsocketServer> webSocketMap = new ConcurrentHashMap<>();/**与某个客户端的连接会话,需要通过它来给客户端发送数据*/private Session session;/**接收userId*/private String userId = "";/*** 连接建立成功调用的方法*/@OnOpenpublic void onOpen(Session session,@PathParam("userId") String userId) {this.session = session;this.userId = userId;if(webSocketMap.containsKey(userId)){//加入set中webSocketMap.put(userId,this);}else{//加入set中webSocketMap.put(userId,this);//在线数加1addOnlineCount();}log.info("用户连接:" + userId + ",当前在线人数为:" + getOnlineCount());try {sendMessage("连接成功");} catch (IOException e) {e.printStackTrace();log.error("用户:"+userId+",网络异常!!!!!!");}}/*** 连接关闭调用的方法*/@OnClosepublic void onClose() {if(webSocketMap.containsKey(userId)){//从set中删除webSocketMap.remove(userId);//人数减一subOnlineCount();}log.info("用户退出:" + userId + ",当前在线人数为:" + getOnlineCount());}/*** 收到客户端消息后调用的方法* @param jsonMessage 客户端发送过来的消息*/@OnMessagepublic void onMessage(String jsonMessage, Session session) {log.info("用户消息:{} ,jsonMessage -> {}", userId, jsonMessage);// 消息持久化 TODOif (StringUtils.isNotBlank(jsonMessage)) {MessageVo messageVo = JSONUtil.toBean(jsonMessage, MessageVo.class);messageVo.setUserId(this.userId); // 增加发送人,防止篡改String toUserId = messageVo.getToUserId();if (StringUtils.isNotBlank(toUserId) && webSocketMap.containsKey(toUserId)) {try {webSocketMap.get(toUserId).sendMessage(messageVo.getContent());} catch (IOException e) {e.printStackTrace();log.error("消息发送错误");}} else {log.info("接收者userId: {}, 当前不在线", toUserId);}}}/**** @param session* @param error*/@OnErrorpublic void onError(Session session, Throwable error) {log.error("用户错误:" + this.userId + ",原因:" + error.getMessage());error.printStackTrace();}/*** 实现服务器主动推送*/public void sendMessage(String message) throws IOException {this.session.getBasicRemote().sendText(message);}/*** 发送自定义消息**/public static boolean sendInfo(String message,@PathParam("userId") String userId) throws IOException {log.info("发送消息到:" + userId + ",报文:" + message);if(StringUtils.isNotBlank(userId) && webSocketMap.containsKey(userId)){webSocketMap.get(userId).sendMessage(message);return true;}else{log.error("用户" + userId + ",不在线!");return false;}}/*** 获取在线人数* @return*/public static synchronized int getOnlineCount() {return onlineCount;}/*** 在线人数加一*/public static synchronized void addOnlineCount() {WebsocketServer.onlineCount++;}/*** 在线人数减一*/public static synchronized void subOnlineCount() {WebsocketServer.onlineCount--;}
}
WebsocketConfig类(这好像是用注解启动服务的,不需要再配置什么启动啥的)
package cn.control.cp.onway.WebScoket;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;@Configuration
@EnableWebSocket
public class WebsocketConfig {@Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter();}
}

前台使用:ts文件

export const WebScoketApi = {// 查询用车申请分页getVehicleApplicationPage: async (params: any) => {return await request.get({ url: `/control/sqs-loadingandshipping-manage/vehicleapplicationpage`, params })},openSocket(socket:any) {if(typeof(WebSocket) == "undefined") {console.log("您的浏览器不支持WebSocket");}else{console.log("您的浏览器支持WebSocket");//实现化WebSocket对象,指定要连接的服务器地址与端口  建立连接//等同于socket = new WebSocket("ws://localhost:8888/xxxx/im/25");//var socketUrl="${request.contextPath}/im/"+$("#userId").val();//var socketUrl="http://localhost:9999/demo/imserver/"+$("#userId").val();let socketUrl="http://localhost:48082/websocket/1";socketUrl=socketUrl.replace("https","ws").replace("http","ws");console.log(socketUrl);if(socket!=null){socket.close();socket=null;}socket = new WebSocket(socketUrl);//打开事件socket.onopen = function() {console.log("websocket已打开");//socket.send("这是来自客户端的消息" + location.href + new Date());};//获得消息事件socket.onmessage = function(msg) {console.log(msg.data);//发现消息进入    开始处理前端触发逻辑};//关闭事件socket.onclose = function() {console.log("websocket已关闭");};//发生了错误事件socket.onerror = function() {console.log("websocket发生了错误");}}
},sendMessage(socket:WebSocket) {if(typeof(WebSocket) == "undefined") {console.log("您的浏览器不支持WebSocket");}else {console.log("您的浏览器支持WebSocket");socket.send('{"toUserId":"'+"#toUserId"+'","contentText":"'+"#contentText"+'"}');}
}
}

VUE文件:


<script setup lang="ts">
import { WebScoketApi } from '@你的ts文件所在路径';
var webSocket;
//在钩子函数上使用该方法即可function connection(){WebScoketApi.openSocket(webSocket)//打开链接// webSocket = new WebSocket("ws://localhost:48082/production/websocket/12");// webSocket.onopen = function (event) {//     console.log("WebSocket opened.");// };// webSocket.onmessage = function (event) {//     console.log("Received message: " + event.data);// };// webSocket.onclose = function (event) {//     console.log("WebSocket closed.");// };} 
</script>

记录这篇文章主要是因为一直报200的错误,后来才发现是被拦截的,修改后已成功通讯。我只是给JAVA大佬打下手的,有不足之处请参考顶部链接。

版权声明:

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

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