All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ars.module.mobile.service.AbstractPushService Maven / Gradle / Ivy

package ars.module.mobile.service;

import java.util.Map;
import java.util.List;
import java.util.concurrent.Callable;

import ars.util.Beans;
import ars.server.Servers;
import ars.module.mobile.app.Device;
import ars.module.mobile.app.Messager;
import ars.module.mobile.model.Push;
import ars.module.mobile.model.Apper;
import ars.module.mobile.service.PushService;
import ars.database.repository.Repositories;
import ars.database.service.StandardGeneralService;
import ars.server.timer.AbstractTimerServer;

/**
 * App消息推送业务操作接口抽象实现
 * 
 * @author yongqiangwu
 * 
 * @param 
 *            数据模型
 */
public abstract class AbstractPushService extends StandardGeneralService implements PushService {
	private int batch = 1000; // 消息同步批次
	private Map messagers;

	public AbstractPushService() {
		this.initSynchronServer();
	}

	public int getBatch() {
		return batch;
	}

	public void setBatch(int batch) {
		if (batch < 1) {
			throw new IllegalArgumentException("Illegal batch:" + batch);
		}
		this.batch = batch;
	}

	public Map getMessagers() {
		return messagers;
	}

	public void setMessagers(Map messagers) {
		this.messagers = messagers;
	}

	/**
	 * 初始化消息同步服务
	 */
	protected void initSynchronServer() {
		new AbstractTimerServer() {

			@Override
			protected void execute() throws Exception {
				synchron();
			}

		}.start();
	}

	/**
	 * 消息同步
	 */
	protected void synchron() {
		int count = this.getRepository().query().count();
		for (int page = 1, total = (int) Math.ceil((double) count / (double) this.batch); page <= total; page++) {
			List pushs = this.getRepository().query().paging(page, this.batch).asc("dateJoined").list();
			for (final T push : pushs) {
				final Apper apper = Repositories.getRepository(Apper.class).query().eq("user", push.getUser()).single();
				if (apper == null) {
					this.getRepository().delete(push);
				} else if (apper.getOnline() == Boolean.TRUE) {
					try {
						Servers.submit(new Callable() {

							@Override
							public Object call() throws Exception {
								messagers.get(apper.getDevice()).push(push.getMessage(), push.getParameters(),
										apper.getChannel());
								return null;
							}

						}).get();
						this.getRepository().delete(push);
					} catch (Exception e) {
						Servers.logger.error("Message push failure", e);
						push.setResend(push.getResend() + 1);
						this.getRepository().update(push);
					}
				}
			}
		}
	}

	@Override
	public void message(String user, final String message, final Map parameters) throws Exception {
		if (this.messagers == null || this.messagers.isEmpty()) {
			throw new RuntimeException("Messager has not been initialize");
		}
		Apper apper = Repositories.getRepository(Apper.class).query().eq("user", user).single();
		if (apper == null) {
			throw new RuntimeException("User does not exist:" + user);
		}
		if (apper.getOnline() == Boolean.TRUE) {
			Messager messager = this.messagers == null ? null : this.messagers.get(apper.getDevice());
			if (messager == null) {
				throw new RuntimeException("Device messager not found:" + apper.getDevice());
			}
			try {
				messager.push(message, parameters, apper.getChannel());
			} catch (Exception e) {
				Servers.logger.error("Message push failure", e);
				T push = Beans.getInstance(this.getModel());
				push.setUser(user);
				push.setMessage(message);
				push.setParameters(parameters);
				this.getRepository().save(push);
			}
		} else {
			T push = Beans.getInstance(this.getModel());
			push.setUser(user);
			push.setMessage(message);
			push.setParameters(parameters);
			this.getRepository().save(push);
		}
	}

}