基于quartz,redis,socket.io的web实时消息推送

功能需求:

    通过quartz(也可以不用quartz,用redis的订阅发布)定时从redis中获得实时数据(可以是通过storm或其他工具分析的数据)推送到web页面展示出来。

实现思路:

    1,可以通过轮询来实现,简单但是比较消耗资源。

    2,使用webSocket实现,与服务端建立长连接,省去重复请求耗费的资源,注意只有H5支持。

使用webSocket实现图:

152818_BiAB_2345870.png

需要依赖的jar包:

<!-- quartz定时任务 -->
<dependency>
			<groupId>org.quartz-scheduler</groupId>
			<artifactId>quartz</artifactId>
			<version>2.2.1</version>
		</dependency>
		<dependency>
			<groupId>org.quartz-scheduler</groupId>
			<artifactId>quartz-jobs</artifactId>
			<version>2.2.1</version>
		</dependency>
<!-- redis java客户端 -->
<dependency> 
			<groupId>redis.clients</groupId>
			<artifactId>jedis</artifactId>
			<version>2.9.0</version>
			<type>jar</type>
			<scope>compile</scope>
		</dependency>
<!-- netty-socketio -->
<dependency>
		  <groupId>com.corundumstudio.socketio</groupId>
		  <artifactId>netty-socketio</artifactId>
		  <version>1.7.8</version>
		</dependency>
<!-- socket.io-client 将redis数据推送到webSocket服务 -->
<dependency>
		    <groupId>io.socket</groupId>
		    <artifactId>socket.io-client</artifactId>
		    <version>1.0.0</version>
		</dependency>

实现代码:

1,webSocket 服务

package com.charhoo.anytest.websocket;

import com.corundumstudio.socketio.Configuration;
import com.corundumstudio.socketio.SocketIOServer;

public class AppServer {
    public static void main(String[] args) throws InterruptedException
    {
        Configuration config = new Configuration();
        config.setHostname("192.168.1.1");//设置ip
        config.setPort(9093);//设置端口

        SocketIOServer server = new SocketIOServer(config);//实例化SocketIOServer 
        CharteventListener listner = new CharteventListener();//设置服务监听
        listner. setServer(server);
        server.addEventListener("timeEvent", ChatObject.class, listner);// timeEvent为事件名称
        
        server.start();//启动服务
        Thread.sleep(Integer.MAX_VALUE) ;
        server.stop();
    }
}

2,quartz定时任务

package com.charhoo.socket.util;

import java.text.ParseException;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;

import com.charhoo.socket.job.RedisAlarmJob;


public class QuartzUtil {
	
	public static Scheduler getScheduler() throws SchedulerException, ParseException {

		SchedulerFactory schedulerFactory = new StdSchedulerFactory();
		Scheduler scheduler = schedulerFactory.getScheduler();

		JobDetail jobDetail = JobBuilder.newJob(RedisAlarmJob.class)
								        .withIdentity("redisAlarmJob", Scheduler.DEFAULT_GROUP)
								        .build();
		
		String cronExpression = "0/5 * * * * ?"; // 每分钟的0s起,每5s触发任务
		CronTrigger cronTrigger = TriggerBuilder.newTrigger()
										       .withIdentity("cronTrigger", Scheduler.DEFAULT_GROUP)  
										       .withSchedule(CronScheduleBuilder.cronSchedule(cronExpression))
										       .build();    
		scheduler.scheduleJob(jobDetail, cronTrigger);

		return scheduler;
	}

}

job

package com.charhoo.socket.job;

import java.util.Map;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import com.charhoo.socket.SocketClient;
import com.charhoo.socket.util.RedisUtil;

public class RedisAlarmJob implements Job {

	public void execute(JobExecutionContext context) throws JobExecutionException {
		// 获取redis报警数据并发布到Socket
		Map<String, String> data = RedisUtil.jedisCluster.hgetAll("youkey");
		SocketClient.getInstance().emit("TimeEvent", data );

	}

}

java-socketClient

package com.charhoo.socket;

import java.net.URISyntaxException;

import org.json.JSONException;
import org.json.JSONObject;

import io.socket.client.IO;
import io.socket.client.Socket;
import io.socket.emitter.Emitter;

public class SocketClient{
	
	private static Socket instance;

	public static synchronized Socket getInstance() {
		if (instance == null) {
			IO.Options options = new IO.Options();    
            options.forceNew = true;
            options.reconnection = true;
            try {
				instance = IO.socket("http://192.168.1.1:9093", options);
				instance.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
	                public void call(Object... args) {
	                    System.out.println("connect");
	                }
	            }).on(Socket.EVENT_CONNECT_TIMEOUT, new Emitter.Listener() {
	                public void call(Object... args) {
	                    System.out.println("connect timeout");
	                }
	            }).on(Socket.EVENT_CONNECT_ERROR, new Emitter.Listener() {
	                public void call(Object... args) {
	                    System.out.println("connect error");
	                }
	            }).on(Socket.EVENT_DISCONNECT, new Emitter.Listener() {
	                public void call(Object... args) {    
	                    System.out.println("disconnect");
	                }
	            }).on("TimeEvent", new Emitter.Listener() {
	                public void call(Object... args) {
	                	System.out.println("服务端:"+args[0]);
	                }
	            });
				instance.open();
			} catch (URISyntaxException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return instance;
	}


}

3,web页面

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Socketio chat</title>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script src="https://cdn.bootcss.com/socket.io/2.0.3/socket.io.js"></script>
<style>
body {
    padding: 20px;
}
#console {
    height: 400px;
    overflow: auto;
}

</style>
</head>
<body>
    <h1>Netty-socketio demo</h1>
    <br />
    <div id="console" class="well"></div>
</body>
<script type="text/javascript">
    var socket = io.connect('http://192.168.1.1:9093');
    socket.on('connect',function() {
        output('<span class="connect-msg">Client has connected to the server!</span>');
    });
    
    socket.on('TimeEvent', function(data) {
        output('<span class="username-msg">' + data.vid + ' : </span>'
                + data.speed);
    });
    
    function output(message) {
        var currentTime = "<span class='time' >" + new Date() + "</span>";
        var element = $("<div>" + currentTime + " " + message + "</div>");
        $('#console').prepend(element);
    }
</script>
</html>

 

启动:

先启动socketServer服务,再启动quartz定时任务,打开web页面就会收到redis的实时数据。

 

讲述的不明确的地方欢迎留言。

转载于:https://my.oschina.net/519617/blog/1523590

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值