websocket实现android消息推送

浏览:
字体:
发布时间:2013-12-09 23:23:14
来源:
  前段时间做一个项目,需要android客户端作为管理工具与web服务器后台实时交互,想了很多方法,包括androidpn、openfire+smack、xmpp协议,要么太繁琐,要么无法满足实时性。想来还是用socket,经人提醒想到了websocket。
 
    websocket协议是近些年随html5发展而诞生的,主要用于解决web服务器与客户端无法双向交互的问题。如今已经被W3C收入标准协议。
    服务器支持:tomcat、jetty的最新版本都已支持websocket;如果不想更换现有服务器,也可用spring4.0作为替代。据说新版本的jre将收入websocket类,没具体接触。
    客户端支持:目前的主流浏览器都已经实现了websocket,但由于前期协议版本变化太快,很多厂商没有跟上。android默认浏览器就不支持websocket,IE也直到IE10才支持。
 
    网上已有通过html实现websocket client的例子,这里我们用java实现客户端连接。废话不说,上Demo:
 
1.服务器端
服务器用了tomcat 7.0,直接使用tomcat的websocket实现
1)连接管理类
[java]  
import java.io.IOException;  
import java.nio.CharBuffer;  
import java.util.ArrayList;  
import java.util.List;  
import org.apache.catalina.websocket.MessageInbound;  
import org.apache.catalina.websocket.WsOutbound;  
  
public class MessageCenter  
{  
    private static MessageCenter        instance           = new MessageCenter();  
  
    private List<MessageInbound>        socketList;  
  
    private MessageCenter()  
    {  
        this.socketList = new ArrayList<MessageInbound>();  
    }  
  
    public static MessageCenter getInstance()  
    {  
        return instance;  
    }  
  
    public void addMessageInbound(MessageInbound inbound)  
    {  
        socketList.add(inbound);  
    }  
  
    public void removeMessageInbound(MessageInbound inbound)  
    {  
        socketList.remove(inbound);  
    }  
  
    public void broadcast(CharBuffer msg) throws IOException  
    {  
        for (MessageInbound messageInbound : socketList)  
        {  
            CharBuffer buffer = CharBuffer.wrap(msg);  
            WsOutbound outbound = messageInbound.getWsOutbound();  
            outbound.writeTextMessage(CharBuffer.wrap("broadcasting:" + msg));  
            // outbound.writeTextMessage(buffer);  
            outbound.flush();  
        }  
    }  
}  
 
2)消息入口类
[java] 
import java.io.IOException;  
import java.nio.ByteBuffer;  
import java.nio.CharBuffer;  
import java.util.Date;  
  
import org.apache.catalina.websocket.MessageInbound;  
import org.apache.catalina.websocket.WsOutbound;  
  
public class MyMessageInbound extends MessageInbound {  
  
    @Override  
    protected void onBinaryMessage(ByteBuffer arg0) throws IOException {  
        // TODO Auto-generated method stub  
          
    }  
  
    @Override  
    protected void onTextMessage(CharBuffer msg) throws IOException {  
        System.out.println("Received:"+msg);  
        MessageCenter.getInstance().broadcast(msg);  
          
    }  
  
    @Override  
    protected void onClose(int status) {  
        System.out.println("close:"+new Date());  
        MessageCenter.getInstance().removeMessageInbound(this);  
        super.onClose(status);  
    }  
  
    @Override  
    protected void onOpen(WsOutbound outbound) {  
        System.out.println("open :"+new Date());  
        super.onOpen(outbound);  
        MessageCenter.getInstance().addMessageInbound(this);  
    }  
}  
 
3)Websocket servlet
[java] 
import javax.servlet.http.HttpServletRequest;  
  
import org.apache.catalina.websocket.StreamInbound;  
import org.apache.catalina.websocket.WebSocketServlet;  
  
public class MeWebSocketServlet extends WebSocketServlet  
{  
  
    private static final long serialVersionUID = -7178893327801338294L;  
  
    @Override  
    protected StreamInbound createWebSocketInbound(String subProtocol, HttpServletRequest request)  
    {  
        System.out.println("##########client login#########");  
        return new MeMessageInbound();  
    }  
  
}  
 
4)添加servlet到web.xml
[html] 
< servlet>  
       < servlet-name> android</ servlet-name >  
       < servlet-class> MyWebSocketServlet </servlet-class >  
</ servlet>  
< servlet-mapping>  
       < servlet-name> android</ servlet-name >  
       < url-pattern> *.do</ url-pattern >  
</ servlet-mapping>  
 
 
2.客户端
    客户端使用java实现websocket client,
    网上有人实现了Java-websocket:https://github.com/TooTallNate/Java-WebSocket 可以取得源码,用maven编译。
    最新jar包下载地址:
    http://download.csdn.net/detail/chifengxin/6524283
 
    引用jar包后,实现简单消息连接:
[java] 
import java.net.URI;  
import java.net.URISyntaxException;  
  
import org.java_websocket.client.WebSocketClient;  
import org.java_websocket.drafts.Draft;  
import org.java_websocket.drafts.Draft_10;  
import org.java_websocket.drafts.Draft_17;  
import org.java_websocket.framing.Framedata;  
import org.java_websocket.handshake.ServerHandshake;  
  
/** This example demonstrates how to create a websocket connection to a server. Only the most important callbacks are overloaded. */  
public class ExampleClient extends WebSocketClient {  
  
        public ExampleClient( URI serverUri , Draft draft ) {  
                super( serverUri, draft );  
        }  
  
        public ExampleClient( URI serverURI ) {  
                super( serverURI );  
        }  
  
        @Override  
        public void onOpen( ServerHandshake handshakedata ) {  
                System.out.println( "opened connection" );  
                // if you plan to refuse connection based on ip or httpfields overload: onWebsocketHandshakeReceivedAsClient  
        }  
  
        @Override  
        public void onMessage( String message ) {  
                System.out.println( "received: " + message );  
        }  
  
        @Override  
        public void onFragment( Framedata fragment ) {  
                System.out.println( "received fragment: " + new String( fragment.getPayloadData().array() ) );  
        }  
  
        @Override  
        public void onClose( int code, String reason, boolean remote ) {  
                // The codecodes are documented in class org.java_websocket.framing.CloseFrame  
                System.out.println( "Connection closed by " + ( remote ? "remote peer" : "us" ) );  
        }  
  
        @Override  
        public void onError( Exception ex ) {  
                ex.printStackTrace();  
                // if the error is fatal then onClose will be called additionally  
        }  
  
        public static void main( String[] args ) throws URISyntaxException {  
                ExampleClient c = new ExampleClient( new URI( "ws://localhost:8080/myweb/android.do" ), new Draft_17() );   
                c.connect();  
        }  
  
}  
注意,连接中使用的new Draft_17()就是使用的协议version,Draft_17支持Tomcat 7.0使用的协议版本RFC 6455。
 
总结websocket的利弊
优点:
与socket相比,可以节省额外的端口占用,直接使用一个公网域名访问。另外协议对报文的流量消耗做了优化。
 
缺点:
毕竟websocket底层也是socket连接,因而当大并发用户连接时目测会消耗较多资源。
>更多相关文章
24小时热门资讯
24小时回复排行
资讯 | QQ | 安全 | 编程 | 数据库 | 系统 | 网络 | 考试 | 站长 | 关于东联 | 安全雇佣 | 搞笑视频大全 | 微信学院 | 视频课程 |
关于我们 | 联系我们 | 广告服务 | 免责申明 | 作品发布 | 网站地图 | 官方微博 | 技术培训
Copyright © 2007 - 2024 Vm888.Com. All Rights Reserved
粤公网安备 44060402001498号 粤ICP备19097316号 请遵循相关法律法规
');})();