Java整合WebSocket实现实时推送(注解版)
第一次写博客,备份下代码,顺便给需要的同学看看,
网上也有很多Java整合webSocket的例子,大多自己写个类继承 WebSocketConfigurer ,
直接使用注解的比较少,我也看了很多写的运行有问题,要么代码关键部分缺少,想着自己弄一个好了,这个版本在网上某些大佬的基础上实现的,基础代码重复写没意义。
1.加入websocket依赖包
<!-- WebSocket --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-websocket</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-messaging</artifactId> <version>${spring.version}</version> </dependency>
2.在Namespaces中勾选websocket
3.配置请求地址
<!-- 配置webSockte --> <!-- 实现webscoket接口 --> <bean id="wsHandler" class="com.spd.sw.websocket.MyMessageHandler"/> <websocket:handlers allowed-origins="*"> <!-- 前端握手请求地址 --> <websocket:mapping path="/socketServer" handler="wsHandler"/> <websocket:handshake-interceptors> <bean class="com.spd.sw.websocket.WebSocketInterceptor"/> </websocket:handshake-interceptors> </websocket:handlers>
4.拦截器配置
public class WebSocketInterceptor extends HttpSessionHandshakeInterceptor {
/**
* TODO 描述该方法的实现功能.
* @see org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor#beforeHandshake(org.springframework.http.server.ServerHttpRequest, org.springframework.http.server.ServerHttpResponse, org.springframework.web.socket.WebSocketHandler, java.util.Map)
*/
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
Map attributes) throws Exception {
if(request instanceof ServletServerHttpRequest){
ServletServerHttpRequest serverHttpRequest = (ServletServerHttpRequest)request;
//获取参数
String userId = serverHttpRequest .getServletRequest().getParameter(“userId”);
attributes.put(MyMessageHandler.USER_KEY, userId);
}
return true; }
}
5.socket用户及msg
/**
- ClassName: MyMessageHandler
- Function: 实现webscoket接口
- @version
*/
@Service
public class MyMessageHandler implements WebSocketHandler {
//用户
public static final String USER_KEY = “socket_user”; /**- userMap:存储用户连接webscoket信息
- @since JDK 1.7
/ private final static int size=300;//用户数量 private final static Map userMap; static { userMap = new ConcurrentHashMap(size); } /* - 关闭websocket时调用该方法
- @see org.springframework.web.socket.WebSocketHandler#afterConnectionClosed(org.springframework.web.socket.WebSocketSession, org.springframework.web.socket.CloseStatus)
*/
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
String userId = this.getUserId(session);
if(StringUtils.isNoneBlank(userId)){
userMap.remove(userId);
System.err.println(userId +”用户已成功关闭会话”);
}else{
System.err.println(“关闭时,获取用户id为空”);
}
- 建立websocket连接时调用该方法
- @see org.springframework.web.socket.WebSocketHandler#afterConnectionEstablished(org.springframework.web.socket.WebSocketSession)
*/
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
String userId = this.getUserId(session);
if(StringUtils.isNoneBlank(userId)){
userMap.put(userId, session);
//session.sendMessage(new TextMessage(“用户”+userId+”建立WebSocket连接成功!”)); //给所有用户发送消息
}
- 客户端调用websocket.send时候,会调用该方法,进行数据通信
- @see org.springframework.web.socket.WebSocketHandler#handleMessage(org.springframework.web.socket.WebSocketSession, org.springframework.web.socket.WebSocketMessage)
*/
@Override
public void handleMessage(WebSocketSession session, WebSocketMessage message) throws Exception {
String msg = message.toString();
String userId = this.getUserId(session);
System.err.println(“该”+userId+”用户发送的消息是:”+msg);
message = new TextMessage(“服务端已经接收到消息,msg=”+msg);
session.sendMessage(message);
- 传输过程出现异常时,调用该方法
- @see org.springframework.web.socket.WebSocketHandler#handleTransportError(org.springframework.web.socket.WebSocketSession, java.lang.Throwable)
*/
@Override
public void handleTransportError(WebSocketSession session, Throwable e) throws Exception {
WebSocketMessage message = new TextMessage(“异常信息:”+e.getMessage());
session.sendMessage(message);
}
- @see org.springframework.web.socket.WebSocketHandler#supportsPartialMessages()
*/
@Override
public boolean supportsPartialMessages() {
}- @see org.springframework.web.socket.WebSocketHandler#supportsPartialMessages()
- sendMessageToUser:发给指定用户
- @param userId
- @param contents
- @since JDK 1.7
*/
public void sendMessageToUser(String userId,String contents) {
WebSocketSession session = userMap.get(userId);
if(session !=null && session.isOpen()) {
try {
TextMessage message = new TextMessage(contents);
session.sendMessage(message);
} catch (IOException e) {
e.printStackTrace();
}
}
} /** - sendMessageToAllUsers:发给所有的用户
- @param contents
- @since JDK 1.7
*/
public void sendMessageToAllUsers(String contents) {
Set userIds = userMap.keySet();
for(String userId: userIds) {
this.sendMessageToUser(userId, contents);
}
}
- getUserId:获取用户id
- @param session
- @return
- @since JDK 1.7
*/
private String getUserId(WebSocketSession session){
try {
String userId = (String)session.getAttributes().get(USER_KEY);
return userId;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
6.在springmvc controller中加入
@RequestMapping(“/socket”)
@Controller
public class WebSocketController {
@Autowired
MyMessageHandler myMessageHandler;
/** * 对单个用户推送消息 * @return * @throws ParseException */ @RequestMapping("/sendMessageByUser") @ResponseBody public String sendMessageByUser(@RequestParam Map<String, Object> contents) throws ParseException{ task(); return "success"; } /** * 对所有用户推送消息 * @return */ @RequestMapping("/sendMessageByAll") @ResponseBody public String sendMessageByAll(@RequestParam Map<String, Object> contents){ myMessageHandler.sendMessageToAllUsers(contents.get("msg").toString()); return "success"; } }
7.前端js
$(document).ready(function () {
window.websocket={};
var userId=’webPower’;
var api=’你的IP’;
var app={
/**
*初始化socket,判断是否支持webSocket
*/
initSocket:function () {
if(‘WebSocket’ in window) {
websocket = new WebSocket(“ws://”+api+”/socketServer?userId=”+userId);
} else if(‘MozWebSocket’ in window) {
websocket = new MozWebSocket(“ws://”+api+”/socketServer?userId=”+userId);
} else {
websocket = new SockJS(“http://”+api+”/sockjs/socketServer?userId=”+userId);
}
app.state();
},
/**
* 状态
*/
state:function () {
// 打开连接时
websocket.onopen = function(evnt) {
console.log(“websocket已启用”);
};
// 收到消息时 websocket.onmessage = { }; //出错时 websocket.onerror = function(evnt) { console.log("与后台握手出现问题!"); }; //关闭时 websocket.onclose = function(evnt) { console.log("正在关闭 webSocket "); }; //发送消息 // websocket.send(msg); } }; app.initSocket();
});
8.效果
作者:lutingzhu9165
来源:CSDN
原文:https://blog.csdn.net/lutingzhu9165/article/details/80576015
版权声明:本文为博主原创文章,转载请附上博文链接!