Websocket androidメッセージプッシュを実現

6711 ワード

この間、androidクライアントが管理ツールとしてwebサーバのバックグラウンドとリアルタイムで対話する必要があり、android pn、openfire+smack、xmppプロトコルなど、多くの方法を考えました.煩雑すぎるか、リアルタイム性を満たすことができません.考えてみればやはりsocketを使って、websocketを思い出したと注意されました.
websocketプロトコルは近年html 5の発展に伴って誕生し、主にwebサーバとクライアントが双方向に対話できない問題を解決するために使用されている.現在、W 3 C収入標準協定が締結されている.
サーバサポート:tomcat、jettyの最新バージョンはwebsocketをサポートしています.既存のサーバを交換したくない場合はspring 4も使用できます.0を置換します.新バージョンのjreはwebsocketクラスに格納されるそうで、具体的な接触はありません.
クライアントサポート:現在の主流ブラウザではwebsocketが実現されていますが、前期のプロトコルバージョンの変化が速すぎて、多くのメーカーがフォローしていません.Androidのデフォルトブラウザではwebsocketはサポートされておらず、IEもIE 10までサポートされていません.
ネット上で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 {

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