概述
websocket实现android消息推送
分类: Android
2013-11-08 13:59
9641人阅读
评论(3)
收藏
举报
前段时间做一个项目,需要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)连接管理类
- 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)消息入口类
- 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
- 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 MyMessageInbound();
- }
- }
4)添加servlet到web.xml
- < 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包后,实现简单消息连接:
- 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.connectBlocking();
- c.send("handshake");
- }
- }
注意,连接中使用的new Draft_17()就是使用的协议version 17(RFC 6455),Tomcat 7.0使用的协议版本为RFC 6455。
总结websocket的利弊
优点:
与socket相比,可以节省额外的端口占用,直接使用一个公网域名访问。另外协议对报文的流量消耗做了优化。
缺点:
毕竟websocket底层也是socket连接,因而当大并发用户连接时目测会消耗较多资源。
参考:
最后
以上就是聪明钢铁侠为你收集整理的websocket实现android消息推送的全部内容,希望文章能够帮你解决websocket实现android消息推送所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复