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<String, Object> 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<String, WebSocketSession> userMap;  
    static {  
        userMap = new ConcurrentHashMap<String,WebSocketSession>(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<String> 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<String> 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.效果



  • 14
    点赞
  • 74
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Java实现WebSocket实现消息推送的步骤如下: 1.创建WebSocket配置类 ```java @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(new MyWebSocketHandler(), "/websocket").addInterceptors(new MyHandshakeInterceptor()); } } ``` 2.创建WebSocket处理器 ```java public class MyWebSocketHandler extends TextWebSocketHandler { private static final List<WebSocketSession> sessions = new CopyOnWriteArrayList<>(); @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { sessions.add(session); } @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { for (WebSocketSession s : sessions) { s.sendMessage(message); } } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception { sessions.remove(session); } } ``` 3.创建握手拦截器 ```java public class MyHandshakeInterceptor implements HandshakeInterceptor { @Override public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception { return true; } @Override public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) { } } ``` 4.在页面中使用JavaScript连接WebSocket ```javascript var socket = new WebSocket("ws://localhost:8080/websocket"); socket.onmessage = function(event) { console.log(event.data); }; ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值