WebSocket实现android消息推送详解编程语言

WebSocket实现android消息推送详解编程语言

前段时间做一个项目,需要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:

一.服务器端

服务器用了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 {  

    }  

    @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>

二.客户端

客户端使用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;  

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” );  

    }  

    @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 ) {  

            System.out.println( “Connection closed by ” + ( remote ? “remote peer” : “us” ) );  

    }  

    @Override  

    public void onError( Exception ex ) {  

            ex.printStackTrace();  

    }  

    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消息推送详解编程语言

转载请注明来源网站:blog.ytso.com谢谢!

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/14707.html

(0)
上一篇 2021年7月19日 17:04
下一篇 2021年7月19日 17:04

相关推荐

发表回复

登录后才能评论