安卓总结之(一)--消息推送

本文很多基本内容木有讲,比如XMPP协议、MQTT协议的具体细节,楼主懒,不断完善中,争取慢慢加进来,传送门 MQTT协议简介

最近项目有要用到消息推送,于是仔细研究了一下消息推送

消息推送原理基本上就是利用Socket长链接,通过设置心跳,来保证自己是在线状态

目前安卓消息推送的几种方案:

XMPP方案:成熟的案例是AndroidPN,网址http://sourceforge.net/projects/androidpn/ 

1、XMPP协议采用xml格式,大致如下

<stream> <presence> </ presence> <message> <body> </body> </message> <iq> </iq> </stream>
2、XMPP安卓实现:Smack客户端jar包 + Openfire (服务器端)+Spark(测试用)
这里要说明一点是,Smack自从4.0版以后默认支持安卓客户端了,可以不用asmack了,但是Smack给的文档里面没有说清楚需要引用的Jar包,一直报错,楼主当时找了好久,终于弄全了,大致需要以下几个Jar包,可能可以精简
smack-android-4.1.5.jar
smack-android-extensions-4.1.5.jar
smack-extensions-4.1.5.jar
smack-core-4.1.5.jar
smack-im-4.1.5.jar
smack-tcp-4.1.5.jar
smack-experimental-4.1.5.jar
jxmpp-core-0.4.1.jar
jxmpp-util-cache-0.4.1.jar
smack-sasl-provided-4.1.5.jar
smack-resolver-minidns-4.1.5.jar
minidns-0.1.7.jar
不过楼主没用XMPP做消息推送,而是用来做即时消息通信了


MQTT(简介就自己百度了)

主要原理是服务端把消息发送到消息中间件Broker,由消息中间件来负责推送到客户端

1、MQTT协议格式:固定头长度只有2个字节,轻量,省流量,但是MQTT是基于消息订阅的,一般不支持点对点推送

2、MQTT消息推送搭建

服务器端:代码基本等同于下面Android客户端

消息中间件Broker的选择:目前支持MQTT协议的有ActiveMQ、Active Apollo(ActiveMQ的下一代产品)、Mosquito等。其实做消息推送,性能主要是看这个Broker能力了。

楼主采用的Apollo,貌似出现过丢失情况


Android客户端(需要添加相关jar,楼主用的是mqtt-client-0.4.0.jar,或者在Eclipse加载org.eclipse.paho.mqtt.java.zip:


/**
 * MQTT消息推送服务
 */
public class MQTTService extends Service {
	
	protected static final String TAG = "MQTTService";
	/**客户端连接标识*/
	private String clientId = "melody";
	private MqttClient mClient;<span style="white-space:pre">	</span><pre name="code" class="java"><span style="white-space:pre">	</span>private static final String userName = "admin";<span style="font-family: Arial, Helvetica, sans-serif;">	</span>
<span style="white-space:pre">	</span>private <span style="font-family: Arial, Helvetica, sans-serif;">static </span>final String userPwd = "password";
<pre name="code" class="java"><span style="white-space:pre">	</span>private static final int Timeout= 20;
<pre name="code" class="java"><span style="white-space:pre">	</span>private <span style="font-family: Arial, Helvetica, sans-serif;">static final </span>int Heart_Interval= 30;
 
 private MemoryPersistence persistence;/**MQTT连接设置*/private MqttConnectOptions options;/**订阅的主题*/private String[] topicFilters = new String[]{ "sport", "movie", "news" };/**消息质量,0表示至多一次,1表示至少一次,2表示只有一次*/private int[] mQos = new int[]{ 0, 0, 1, 2 };/**消息主题*/private MqttTopic mTopic;private MqttMessage mMessage;private NotificationManager mManager;private Notification.Builder builder;private int notiId = 1;/** */@Overridepublic IBinder onBind(Intent intent) {return null;}/** * 创建时初始化,MQTTClinet,并连接 */@Overridepublic void onCreate() {mManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);builder = new Notification.Builder(this);builder.setSmallIcon(R.drawable.app_icon);PendingIntent intent = PendingIntent.getActivity(this, 1, new Intent(this, MQTTTestActivity.class),PendingIntent.FLAG_CANCEL_CURRENT );builder.setContentIntent(intent); 
 

		try {
			persistence = new MemoryPersistence();
			mClient = new MqttClient(Constants.SERVER_NOTIFY_URI, clientId, persistence);
			
			options = new MqttConnectOptions();<span style="font-family: Arial, Helvetica, sans-serif;">			</span>
			options.setCleanSession(false);        <span style="font-family: Arial, Helvetica, sans-serif;">//设置离线是否清理session</span>
			options.setUserName(<span style="font-family: Arial, Helvetica, sans-serif;">userName</span><span style="font-family: Arial, Helvetica, sans-serif;">);</span>
			options.setPassword(<span style="font-family: Arial, Helvetica, sans-serif;">userPwd</span><span style="font-family: Arial, Helvetica, sans-serif;">.toCharArray());</span>
			options.setConnectionTimeout(<span style="font-family: Arial, Helvetica, sans-serif;">Timeout</span><span style="font-family: Arial, Helvetica, sans-serif;">);</span>
			options.setKeepAliveInterval(<span style="font-family: Arial, Helvetica, sans-serif;">Heart_Interval</span><span style="font-family: Arial, Helvetica, sans-serif;">);</span>
			
			mClient.setCallback(callback);
			
			mClient.connect(options);
			
			mClient.subscribe(topicFilters, mQos);  <span style="font-family: Arial, Helvetica, sans-serif;">//定阅主题</span>
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		super.onCreate();
	}
	
	/**
	 * 消息回调
	 */
	@SuppressLint("NewApi")
	private MqttCallback callback = new MqttCallback() {
		/**消息到来时,通知栏显示*/
		@Override
		public void messageArrived(String arg0, MqttMessage msg) throws Exception {
			String content = new String(msg.getPayload(), "utf-8");
			Log.e(TAG, "Message From Server Arrived: " + content);
			mManager.notify(notiId, builder.build());
		}
		
		@Override
		public void deliveryComplete(IMqttDeliveryToken token) {
			Log.e(TAG, "Delivery Complete");
		}
		/**连接丢失时,重新连接*/
		@Override
		public void connectionLost(Throwable e) {
			Log.e(TAG, "连接出现错误");
			try {
				mClient.connect();
			} catch (Exception e1) {
				e1.printStackTrace();
			}
		}
	};
	/**发布消息*/
	public void publishMessage(String topic, int qos, String message){
		mTopic = mClient.getTopic(topic);
		
		mMessage = new MqttMessage();
		mMessage.setQos(qos);
		mMessage.setRetained(true);
		try {
			mMessage.setPayload(message.getBytes("utf-8"));
		} catch (UnsupportedEncodingException e1) {
			e1.printStackTrace();
		}
		try {		
			MqttDeliveryToken token = mTopic.publish(mMessage);
			token.waitForCompletion();
			//Log.e(TAG, "Publish Message: " + token.isComplete());
		} catch (MqttException e) {
			e.printStackTrace();
		}
	}
}

其他的方案有谷歌的C2DM、第三方推送如极光推送等等


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值