最简单的android推送client模型,特点:读写使用同一线程,逻辑非常简单;断线重连;心跳;发消息等。要求不高的基本可以凑合用了呵呵。
package com.example.nbctts; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketTimeoutException; import java.util.Iterator; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingQueue; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import com.example.nbctts.model.ITask; import com.example.nbctts.model.RcvMsg; import com.example.nbctts.model.SendMsg; import com.example.nbctts.model.Status; import com.google.gson.Gson; /* * 1.Timer控制任务投放节奏 * 2.用单线程池控制任务线程顺序执行 * 3.用socket.setSoSocketTime(timeout)及SocketTimeoutException控制阻塞读时间 */ public class MainActivity extends Activity { EditText msgEdt; Button sendBtn; TextView serverTxt; protected final ExecutorService singleThreadExecutor = Executors .newSingleThreadExecutor(); protected final BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>();// 任务队列 protected Socket socket = null; protected Socket rcvSocket = null; protected BufferedReader mReader;// BufferedWriter 用于推送消息 protected BufferedWriter mWriter;// BufferedReader 用于接收消息 protected Gson gson = new Gson(); protected Timer timer = new Timer(); /* * 队列中是否已有该类型的任务 */ private boolean isTaskExist(int msgType) { Iterator<Runnable> it = queue.iterator(); while (it.hasNext()) { ITask task = (ITask) it.next(); if (task.getID() == msgType) { return true; } } return false; } /* * 添加到队列,除了发送消息任务以外,其它不重复添加到队列 */ private void addQueue(Runnable task) { int id = ((ITask) task).getID(); try { if (id == Status.MSG_H) { queue.put(task); } else { if (!isTaskExist(id)) { queue.put(task); } } } catch (Exception e) { e.printStackTrace(); } } /* * 线程消息处理,提交任务到待处理队列 */ public Handler myHandler = new Handler() { @Override public void handleMessage(Message msg) { HandlerMsg m = (HandlerMsg) msg.obj; switch (msg.what) { case Status.CONN_H: serverTxt.append(m.content + "\n"); // 连接不成功,自动重连 if (!m.successFlag) { timer.schedule(new TimerTask() { @Override public void run() { addQueue(new connTask()); } }, Status.getConnIntervel()); } break; case Status.LOGIN_H: serverTxt.append(m.content + "\n"); break; case Status.SVRMSG_H: serverTxt.append(m.content + "\n"); break; case Status.HEARTBEAT_H: // 暂不处理 break; case Status.MSG_H: // 暂不处理 case Status.LOGOUT_H: // 暂不处理 break; default: break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); msgEdt = (EditText) findViewById(R.id.msgEdt); sendBtn = (Button) findViewById(R.id.sendBtn); serverTxt = (TextView) findViewById(R.id.serverTxt); // 启动任务处理线程 new TaskThread().start(); addQueue(new connTask()); // 定时读推送消息/心跳,这里可以分开:) timer.schedule(new TimerTask() { @Override public void run() { addQueue(new RcvTask()); addQueue(new HeartBeatTask()); } }, 1000, Status.heartBeat); sendBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { String str = msgEdt.getText().toString(); serverTxt.append("client:" + str + "\n"); addQueue(new sendTask(str)); } }); } /* * 处理的消息 */ class HandlerMsg { public HandlerMsg(boolean successFlag, String content) { this.successFlag = successFlag; this.content = content; } private boolean successFlag; private String content; } /* * 任务处理线程 */ class TaskThread extends Thread { @Override public void run() { while (true) { if (!queue.isEmpty()) { try { singleThreadExecutor.execute(queue.take()); } catch (InterruptedException e) { e.printStackTrace(); } } } } } /* * 1.连接服务器任务 */ class connTask implements Runnable, ITask { @Override public void run() { if (!Status.isConnected) { socket = new Socket(); try { socket.setKeepAlive(true); socket.setSoTimeout(Status.readBlock); socket.connect( new InetSocketAddress("169.169.43.56", 9999), Status.connTimeout); mReader = new BufferedReader(new InputStreamReader( socket.getInputStream(), "utf-8")); mWriter = new BufferedWriter(new OutputStreamWriter( socket.getOutputStream(), "utf-8")); Status.isConnected = true; Status.reConNum = 0; Message msg = new Message(); msg.what = Status.CONN_H; msg.obj = new HandlerMsg(true, "connTask:已连接到服务器"); myHandler.sendMessage(msg); // 连接成功,则尝试登录 queue.add(new loginTask()); } catch (IOException e) { Status.isConnected = false; Status.isLogin = false; Status.reConNum++; Message msg = new Message(); msg.what = Status.CONN_H; msg.obj = new HandlerMsg(false, "connTask:无法连接到服务器"); myHandler.sendMessage(msg); } } } @Override public int getID() { return Status.CONN_H; } } /* * 2.登录到服务器任务 */ class loginTask implements Runnable, ITask { @Override public void run() { try { if (Status.isConnected) { SendMsg sm = new SendMsg(); sm.setOpt("LOGIN"); sm.setUser(Status.username); sm.setPassword(Status.password); String s = gson.toJson(sm, SendMsg.class); mWriter.write(s + "\n"); mWriter.flush(); // 服务器回复 String rs = mReader.readLine().trim(); RcvMsg rm = gson.fromJson(rs, RcvMsg.class); if (rm.getContent().equals("ok")) { Status.isLogin = true; Message msg = new Message(); msg.what = Status.LOGIN_H; msg.obj = new HandlerMsg(true, "loginTask:已登录到服务器"); myHandler.sendMessage(msg); } else { Status.isLogin = false; Message msg = new Message(); msg.what = Status.LOGIN_H; msg.obj = new HandlerMsg(false, "loginTask:登录到服务器失败:" + rm.getContent()); myHandler.sendMessage(msg); } } } catch (SocketTimeoutException e) { e.printStackTrace(); } catch (IOException e) { Status.isConnected = false; Status.isLogin = false; Message msg = new Message(); msg.what = Status.CONN_H; msg.obj = new HandlerMsg(false, "loginTask:无法连接到服务器"); myHandler.sendMessage(msg); } } @Override public int getID() { return Status.LOGIN_H; } } /* * 3.接收服务器消息任务 */ class RcvTask implements Runnable, ITask { @Override public void run() { if (Status.isConnected && Status.isLogin) { try { String line = ""; while ((line = mReader.readLine()) != null) { RcvMsg rm = gson.fromJson(line, RcvMsg.class); // 目前只接收推来的消息 if (rm != null && rm.getOpt().equals("SVRMSG")) { Message msg = new Message(); msg.what = Status.SVRMSG_H; msg.obj = new HandlerMsg(true, rm.getContent()); myHandler.sendMessage(msg); } } } catch (SocketTimeoutException e) { e.printStackTrace(); } catch (IOException e) { Status.isConnected = false; Message msg = new Message(); msg.what = Status.CONN_H; msg.obj = new HandlerMsg(false, "RcvTask:无法连接到服务器"); myHandler.sendMessage(msg); } } } @Override public int getID() { return Status.SVRMSG_H; } } /* * 4.心跳 */ class HeartBeatTask implements Runnable, ITask { @Override public void run() { if (Status.isConnected && Status.isLogin) { try { SendMsg sm = new SendMsg(); sm.setOpt("HEARTBEAT"); sm.setUser(Status.username); sm.setPassword(Status.password); String s = gson.toJson(sm, SendMsg.class); mWriter.write(s + "\n"); mWriter.flush(); } catch (IOException e) { Status.isConnected = false; Message msg = new Message(); msg.what = Status.CONN_H; msg.obj = new HandlerMsg(false, "HeartBeatTask:无法连接到服务器"); myHandler.sendMessage(msg); } } } @Override public int getID() { return Status.HEARTBEAT_H; } } /* * 5.发送消息 */ class sendTask implements Runnable, ITask { final String str; public sendTask(String str) { this.str = str; } @Override public void run() { if (Status.isConnected && Status.isLogin) { try { SendMsg sm = new SendMsg(); sm.setOpt("MSG"); sm.setUser(Status.username); sm.setPassword(Status.password); sm.setTargetUser("");// 暂时这样 sm.setContent(str); String s = gson.toJson(sm, SendMsg.class); mWriter.write(s + "\n"); mWriter.flush(); } catch (IOException e) { Status.isConnected = false; Message msg = new Message(); msg.what = Status.CONN_H; msg.obj = new HandlerMsg(false, "sendTask:无法连接到服务器"); myHandler.sendMessage(msg); } } else { // 发送消息时如果未连接,马上重连 Status.reConNum = 0; addQueue(new connTask()); } } @Override public int getID() { return Status.MSG_H; } } }
界面不贴,很简单一个输入框输消息内容,一个按钮发消息,一个文本框记录log及服务端推过来的消息,只是一个测试demo。
经测试:断线重连,连接后自动登录,心跳,发消息都没问题,就是接收服务端推送时有延时,这个没办法,毕竟是间隔读,其实也可以把间隔搞小一点。
一般推送对实时性要求不是很高吧,所以基本上可以用。
其实用BlockingQueue,搞成和asmack那样也可以,我这个也算种思路么,哈哈,记录之。
相关推荐
Netty 是一个高性能、异步事件驱动的网络应用程序框架,常用于开发服务器和客户端的通信应用,如TCP、UDP和HTTP等协议。...在实际项目中,理解并熟练掌握这些知识点对于构建稳定高效的Android推送系统至关重要。
本文将深入探讨如何使用MQTT协议在Android平台上实现推送服务,包括服务端和客户端的代码实现。 一、MQTT协议基础 1. **协议特点**:MQTT设计目标是低开销、低带宽和高可靠性,适用于移动设备和网络条件差的环境。...
7. **推送通知**:为了实时接收新消息,可以集成Firebase Cloud Messaging (FCM) 提供的推送服务。 8. **数据库存储**:本地数据持久化通常使用SQLite数据库,用于存储用户会话、未读消息等信息。 **PC服务器端** ...
在"mina及时推送客户端服务端实现"的项目中,我们将会探讨如何利用MINA来实现实时推送功能,并保持客户端和服务端的长连接。 1. **实时推送**:实时推送是现代应用中常见的一种需求,如消息通知、直播互动等。MINA...
本文将深入探讨Android平台上实现MQTT消息推送的相关知识点。 ### MQTT协议简介 MQTT协议基于TCP/IP协议栈,采用发布/订阅模型。在这个模型中,客户端可以作为发布者发送消息,也可以作为订阅者接收消息。消息主题...
7. **通知和推送**:为了让用户及时获取新消息,新闻客户端通常会集成推送服务,如Firebase Cloud Messaging (FCM)。开发者需要了解如何配置和使用这些服务。 8. **UI设计和Material Design**:Android提倡使用...
5. **消息推送机制**:在仿QQ应用中,可能会使用到长轮询、WebSocket或者GCM/FCM(Google Cloud Messaging / Firebase Cloud Messaging)来实现实时消息推送。 6. **数据库操作**:SQLite是Android内置的轻量级...
综上所述,基于百度云推送实现的Android推送聊天涉及到多个技术环节,包括服务的集成、消息模型的设计、用户界面的构建以及性能优化等多个方面。开发者需要对Android系统、网络通信、安全机制以及用户体验有深入理解...
8. **推送通知**:为了让用户及时获取新内容,应用可能集成了推送服务,如Firebase Cloud Messaging(FCM)或其他第三方推送服务。 9. **测试与调试**:开发过程中,单元测试、集成测试和UI测试是必不可少的,JUnit...
5. **通知与推送**:可能有实现即时新闻推送的功能,这涉及到Firebase Cloud Messaging (FCM) 或其他推送服务的集成。 6. **用户界面**:设计和实现用户友好的交互,如滑动刷新、下拉加载更多等。 7. **权限管理**...
总的来说,"基于Netty框架的Android内网推送demo"提供了一个基础的Android内网通信模型,开发者可以在此基础上根据具体需求进行扩展,实现更复杂的功能,例如多用户聊天、实时游戏同步等。通过学习和理解这个Demo,...
4. Android推送服务:如Google的Firebase Cloud Messaging (FCM),用于实现实时消息推送,提高用户体验。 通过对这个仿QQ客户端及服务端源码的学习,开发者不仅能了解Android应用的基本架构,还能深入理解即时通讯...
在IT行业中,消息推送是一项关键的技术,...综上所述,"push(实现消息推送)"项目涵盖了服务器端推送服务的实现和Android客户端的集成,涉及到网络通信、推送协议、消息处理等多个方面,是移动应用开发中的重要技术。
8. **通知与推送**: 如果需要实现实时新闻更新通知,可以集成Firebase Cloud Messaging (FCM) 或其他推送服务。 9. **权限管理**: 根据Android权限模型,可能需要请求用户授予网络访问权限。 10. **UI优化**: 为了...
在Android推送服务中,MQTT可以作为高效、可靠的数据推送机制,尤其适合电量和网络资源有限的设备。 在“MQTT方式实现Android推送服务器端”这个主题中,我们需要关注以下几个关键知识点: 1. **MQTT协议原理**:...
总结,这个压缩包中的源码可以帮助开发者理解如何实现一个完整的Android消息推送系统,包括服务器端的构建和客户端的集成。通过学习并修改这些源码,开发者可以快速地在自己的应用中实现类似功能,提高用户体验。...
在"Android-fpush"项目中,服务器端主要负责接收消息、处理消息并推送给客户端。这通常包括以下几个关键步骤: 1. 客户端建立连接:客户端使用Netty客户端模块与服务器建立长连接。 2. 消息编码与解码:使用protobuf...
`AndroidPushNotifications.zip`可能包含了如何结合MQTT协议发送Android推送通知的示例。当收到MQTT消息时,应用可以触发系统级的通知,让用户知道新消息的到来。这通常涉及到使用`NotificationCompat.Builder`创建...