spring+quartz+websocket做定时消息的推送

在是spring的配置文件中添加schema:

xmlns:websocket="http://www.springframework.org/schema/websocket"
xmlns:task="http://www.springframework.org/schema/task"
http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket.xsd http://www.springframework.org/schema/task    http://www.springframework.org/schema/task/spring-task-3.1.xsd
<!--定时任务注解扫描-->
	<task:annotation-driven/> 

以下是后台代码

//定时任务
@Component
public class AnnotationQuartz {  
    @Scheduled(cron = "0/10 * * * * ? ")  
    public void test() {  
    	//获取WebSocketServer对象的映射。
        ConcurrentHashMap<String, WebSocketServer> map = WebSocketServer.getWebSocketMap();
        if (map.size() != 0){
            for (Map.Entry<String, WebSocketServer> entry : map.entrySet()) {
                WebSocketServer webSocketServer = entry.getValue();
                try {
                    //向客户端推送消息
                	String venderId = entry.getKey();
                	System.out.println("venderId==============="+venderId);
                	if("001".equals(venderId)){
                		webSocketServer.getSession().getBasicRemote().sendText("有新的vip车辆进入三公里范围内,请做好厂内接货准备");
                	}else{
                		webSocketServer.getSession().getBasicRemote().sendText("每隔60秒,向客户端推送一次数据,mp3路径为:/static/mp3/i2.mp3");
                	}
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
        }else {
           // System.out.println("WebSocket未连接");
        }
    }  
}
//socket服务
@ServerEndpoint(value = "/socket/{venderId}")
@Component
public class WebSocketServer {
	
	private static final Logger logger = LoggerFactory.getLogger(WebSocketServer.class);

    //用来记录当前在线连接数
    private static int onLineCount = 0;

    //用来存放每个客户端对应的WebSocketServer对象
    private static ConcurrentHashMap<String,WebSocketServer> webSocketMap = new ConcurrentHashMap<String, WebSocketServer>();

    //某个客户端的连接会话,需要通过它来给客户端发送数据
    private Session session;

    //客户端的登录的用户Id
    private String venderId;

    /**
     * 连接建立成功,调用的方法,与前台页面的onOpen相对应
     * @param venderId 
     * @param session 会话
     */
    @OnOpen
    public void onOpen(@PathParam("venderId")  String venderId,Session session){
        //根据业务,自定义逻辑实现
        this.session = session;
        this.venderId = venderId;
        webSocketMap.put(venderId,this);  //将当前对象放入map中
        addOnLineCount();  //在线人数加一
        logger.info("有新的连接加入,venderId:{}!当前在线人数:{}",venderId,getOnLineCount());
    }

    /**
     * 连接关闭调用的方法,与前台页面的onClose相对应
     * @param venderId
     */
    @OnClose
    public void onClose(@PathParam("venderId")String venderId){
        webSocketMap.remove(venderId);  //根据venderId(key)移除WebSocketServer对象
        subOnLineCount();
        logger.info("WebSocket关闭,venderId:{},当前在线人数:{}",venderId,getOnLineCount());
    }

    /**
     * 当服务器接收到客户端发送的消息时所调用的方法,与前台页面的onMessage相对应
     * @param message
     * @param session
     */
    @OnMessage
    public void onMessage(String message,Session session){
        //根据业务,自定义逻辑实现
    	 logger.info("收到客户端的消息:{}"+message);
    }

    /**
     * 发生错误时调用,与前台页面的onError相对应
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session,Throwable error){
    	logger.info("WebSocket发生错误");
        error.printStackTrace();
    }


    /**
     * 给当前用户发送消息
     * @param message
     */
    public void sendMessage(String message){
        try{
            //getBasicRemote()是同步发送消息,这里我就用这个了,推荐大家使用getAsyncRemote()异步
            this.session.getBasicRemote().sendText(message);
        }catch (IOException e){
            e.printStackTrace();
            logger.info("发送数据错误:,venderId:{},message:{}",venderId,message);
        }
    }

    /**
     * 给所有用户发消息
     * @param message
     */
    public static void sendMessageAll(final String message){
        //使用entrySet而不是用keySet的原因是,entrySet体现了map的映射关系,遍历获取数据更快。
        Set<Map.Entry<String, WebSocketServer>> entries = webSocketMap.entrySet();
        for (Map.Entry<String, WebSocketServer> entry : entries) {
            final WebSocketServer webSocketServer = entry.getValue();
            //这里使用线程来控制消息的发送,这样效率更高。
            new Thread(new Runnable() {
                public void run() {
                    webSocketServer.sendMessage(message);
                }
            }).start();
        }
    }

    /**
     * 获取当前的连接数
     * @return
     */
    public static synchronized int getOnLineCount(){
        return WebSocketServer.onLineCount;
    }

    /**
     * 有新的用户连接时,连接数自加1
     */
    public static synchronized void addOnLineCount(){
        WebSocketServer.onLineCount++;
    }

    /**
     * 断开连接时,连接数自减1
     */
    public static synchronized void subOnLineCount(){
        WebSocketServer.onLineCount--;
    }

    public Session getSession(){
        return session;
    }
    public void setSession(Session session){
        this.session = session;
    }

    public static ConcurrentHashMap<String, WebSocketServer> getWebSocketMap() {
        return webSocketMap;
    }

    public static void setWebSocketMap(ConcurrentHashMap<String, WebSocketServer> webSocketMap) {
        WebSocketServer.webSocketMap = webSocketMap;
    }
}
//后台测试
@Controller
@RequestMapping("/test/websocket")
public class TestWebSocketController {
	 @RequestMapping(value = "/home",method = RequestMethod.GET)
	 public ModelAndView goMain(HttpServletRequest request){
		 ModelAndView view=new ModelAndView();
		 view.setViewName("/index");
		 return view;
	 }
}
<!--前端页面-->
<html>
<head>
    <title>聊天</title>
    
    <script type="text/javascript">
    
    
        //判断当前浏览器是否支持WebSocket
        var webSocket = null;
        if ('WebSocket' in window) {
            webSocket = new WebSocket("ws://127.0.0.1:81/socket/001");
        }
        else if ('MozWebSocket' in window) {
            webSocket = new MozWebSocket("ws://127.0.0.1:81/socket/001");
        }
        else {
            alert('Not support webSocket');
        }

        //打开socket,握手
        webSocket.onopen = function (event) {
            alert("websocket已经连接");
        }
        //接收推送的消息
        webSocket.onmessage = function (event) {
            console.info(event);
              var msg = event.data;
        	alert(msg);
            
        }
        //错误时
        webSocket.onerror = function (event) {
            console.info("发生错误");
            alert("websocket发生错误" + event);
        }

        //关闭连接
        webSocket.onclose = function () {
            console.info("关闭连接");
        }

        //监听窗口关闭
        window.onbeforeunload = function (event) {
            webSocket.close();
        }
    </script>
</head>
<body>
	<div id="content"></div>
</body>
</html>

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值