websocket实现android消息推送
16lz
2021-01-24
前段时间做一个项目,需要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)连接管理类
2)消息入口类
3)Websocket servlet
4)添加servlet到web.xml
2.客户端 客户端使用java实现websocket client, 网上有人实现了Java-websocket: https://github.com/TooTallNate/Java-WebSocket 可以取得源码,用maven编译。 最新jar包下载地址: http://download.csdn.net/detail/chifengxin/6524283
引用jar包后,实现简单消息连接:
总结websocket的利弊 优点: 与socket相比,可以节省额外的端口占用,直接使用一个公网域名访问。另外协议对报文的流量消耗做了优化。
缺点: 毕竟websocket底层也是socket连接,因而当大并发用户连接时目测会消耗较多资源。
参考: Tomcat 7.0 api http://tomcat.apache.org/tomcat-7.0-doc/api/
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 socketList;private MessageCenter(){this.socketList = new ArrayList();}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 {@Overrideprotected void onBinaryMessage(ByteBuffer arg0) throws IOException {// TODO Auto-generated method stub}@Overrideprotected void onTextMessage(CharBuffer msg) throws IOException {System.out.println("Received:"+msg);MessageCenter.getInstance().broadcast(msg);}@Overrideprotected void onClose(int status) {System.out.println("close:"+new Date());MessageCenter.getInstance().removeMessageInbound(this);super.onClose(status);}@Overrideprotected 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;@Overrideprotected 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> < 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连接,因而当大并发用户连接时目测会消耗较多资源。
参考: Tomcat 7.0 api http://tomcat.apache.org/tomcat-7.0-doc/api/
更多相关文章
- 【建议收藏】2020年中高级Android大厂面试秘籍,为你保驾护航金三
- Android(安卓)设备连接电脑显示offline
- android wifi开发
- AIDL的实现
- android多媒体框架之流媒体框架----base on jellybean(九)
- MQTT+ApolloServer实现Android的消息推送功能
- Android(安卓)提交数据到服务器
- Android(安卓)Studio 使用jdbc远程连接阿里云主机web数据库(逃坑)
- Android中关于C2DM开发的一点总结