基于Servlet3.0的服务端消息推送,android应用
2012-09-29 15:09
381 查看
思路:使用Servlet3.0的AsyncContext将客户端请求响应保存起来,当服务端有数据变更时再响应,使用请求轮询的方式保持客户端和服务端的连接。
服务端tomcat7+servlet3.0:
@WebServlet(urlPatterns="/server",asyncSupported=true)
publicclassMessageServerextendsHttpServlet{
//TODO任务队列,还没实现
ConcurrentLinkedQueue<String>taskQueue=newConcurrentLinkedQueue<String>();
//请求响应队列
ConcurrentLinkedQueue<AsyncContext>contextQueue=newConcurrentLinkedQueue<AsyncContext>();
@Override
protectedvoiddoGet(HttpServletRequestreq,HttpServletResponseresp)throwsServletException,IOException{
doPost(req,resp);
}
protectedvoiddoPost(finalHttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
Stringflag=request.getParameter("flag");
Stringtask=StringUtil.Stream2String(request.getInputStream());
System.out.println(task);
if(StringUtil.NotEmpty(flag)){
//客户端有数据发送过来
if("client".equals(flag)&&StringUtil.NotEmpty(task)){
// taskQueue.offer(task);
push(task);
}elseif("receiver".equals(flag)){
//响应客户端
response.getWriter().flush();
finalAsyncContextasyncContext=request.startAsync();
newThread(){
publicvoidrun(){
asyncContext.setTimeout(0);
contextQueue.offer(asyncContext);
System.out.println("现有接收方:"+contextQueue.size());
};
}.start();
}
}
}
/**
*从响应请求队列取出响应对象,逐一响应
*@paramtask
*@throwsIOException
*/
privatesynchronizedvoidpush(Stringtask)throwsIOException{
while(!contextQueue.isEmpty()){
AsyncContextasyncContext=contextQueue.poll();
HttpServletResponseresponse=(HttpServletResponse)asyncContext.getResponse();
response.getWriter().println(task);
response.setStatus(HttpServletResponse.SC_OK);
asyncContext.complete();
}
}
}
接收端(android客户端):
=========MasycTask.java异步任务类===========
publicclassMasyncTaskextendsAsyncTask<URL,String,Void>{
TextViewinfo;
booleanflag;
HttpURLConnectionconn;
publicMasyncTask(TextViewinfo){
this.info=info;
}
protectedVoiddoInBackground(URL...urls){
try{
HttpURLConnectionconn=(HttpURLConnection)urls[0].openConnection();
conn.setConnectTimeout(5000);
this.conn=conn;
if(conn.getResponseCode()==HttpURLConnection.HTTP_OK){
if(!flag){
publishProgress("成功连接服务器!");
flag=true;
}
//将服务端返回的信息发送到前台方法
Stringstring=StringUtil.Stream2String(conn.getInputStream());
if(StringUtil.NotEmpty(string)){
publishProgress(string);
}
doInBackground(urls);
}
}catch(IOExceptione){
publishProgress("网络连接异常!"+e.getMessage());
}
returnnull;
}
protectedvoidonProgressUpdate(String...values){
info.append(values[0]+"\n");
}
publicvoidmCancel(){
conn.disconnect();
conn=null;
}
}
===========MainActivity.java================
publicclassMainActivityextendsActivity{
TextViewinfo;
MasyncTaskasyncTask;
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
info=(TextView)findViewById(R.id.info);
try{
asyncTask=newMasyncTask(info);
asyncTask.execute(newURL("http://192.168.1.100:8080/MessageServer/server?flag=receiver"));
}catch(MalformedURLExceptione){
info.append("URL解析异常!\n");
}
}
@Override
protectedvoidonDestroy(){
//中断连接
asyncTask.mCancel();
super.onDestroy();
}
}
发送端(android客户端):
==========MTask.java========
publicclassMtaskextendsAsyncTask<String,Void,String>{
EditTextmsg;
Contextcontext;
publicMtask(EditTextmsg,Contextcontext){
this.msg=msg;
this.context=context;
}
protectedStringdoInBackground(String...strUrl){
Stringresult=null;
try{
Stringstring=msg.getText().toString();
if(StringUtil.NotEmpty(string)){
HttpPostmethod=newHttpPost(strUrl[0]);
HttpConnectionParams.setConnectionTimeout(method.getParams(),5000);
HttpEntityentity=newStringEntity(string,"UTF-8");
method.setEntity(entity);
//执行请求,如果中途想终止请求可以使用abort()
HttpResponseresponse=newDefaultHttpClient().execute(method);
if(response.getStatusLine().getStatusCode()==HttpStatus.SC_OK){
result="发送成功!";
}
}
}catch(IOExceptione){
result="网络连接异常!"+e.getMessage();
}
returnresult;
}
protectedvoidonPostExecute(Stringresult){
Toast.makeText(context,result,Toast.LENGTH_SHORT).show();
}
}
============MainActivity.java=============
publicclassMainActivityextendsActivity{
EditTextmsg;
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
msg=(EditText)findViewById(R.id.msg);
}
publicvoidsendMsg(Viewv){
newMtask(msg,this).execute("http://192.168.1.100:8080/MessageServer/server?flag=client");
}
}
服务端tomcat7+servlet3.0:
接收端(android客户端):
=========MasycTask.java异步任务类===========
发送端(android客户端):
==========MTask.java========
EditTextmsg;
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
msg=(EditText)findViewById(R.id.msg);
}
publicvoidsendMsg(Viewv){
newMtask(msg,this).execute("http://192.168.1.100:8080/MessageServer/server?flag=client");
}
}
相关文章推荐
- 基于xmpp协议向android推送消息
- 基于MQTT实现Android消息推送(Push)
- php做推送服务端实现android消息推送
- php做推送服务端实现android消息推送
- Android消息推送(二)--基于MQTT协议实现的推送功能
- 基于MQTT实现Android消息推送(Push…
- android 推送消息 php做推送服务端(参考与http://fanfq.iteye.com/blog/1405385)
- Android 基于Netty的消息推送方案之对象的传递(四)
- Android推送通知的实现--PHP+ANDROID做消息推送:基于IBM的MQTT协议的Tokudu项目测试
- android基于百度云消息推送通知集成
- 基于MQTT协议推送Android消息
- 基于MQTT实现Android消息推送(Push)(2)
- Android 基于Netty的消息推送方案之Hello World(一)
- 基于openfire+smack的Android、消息推送服务
- Android 基于Netty的消息推送方案之概念和工作原理(二)
- 友盟消息推送服务端接口(android)
- 基于AndroidPN搭建Android的推送平台 - 离线消息的推送
- Android 基于Netty的消息推送方案之概念和工作原理(二)
- Android消息推送(二)--基于MQTT协议实现的推送功能
- 基于Netty实现的Android 消息推送(即时通信)的解决方案