Java整合WebSocket实现实时推送(注解版)

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() {
      return false;
      }
    /**
    • 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
    版权声明:本文为博主原创文章,转载请附上博文链接!

    发表评论

    邮箱地址不会被公开。

    此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据