Android--WebSocket

  1. 云栖社区>
  2. 博客>
  3. 正文

Android--WebSocket

sealin 2018-03-20 15:00:44 浏览597
展开阅读全文
版权声明:本文为博主原创文章,转载请标明出处。 https://blog.csdn.net/chaoyu168/article/details/79625691

        WebSocket 是一种双向通信协议,在建立连接后,WebSocket服务器和 Browser/Client Agent 都能主动的向对方发送或接收数据,就像 Socket一样。它类似TCP长连接,但是WebSocket使用的是ws和wss两种通信协议,所以这是完全不同于HTTP的一种网络协议,尽管它也是默认使用80和443端口。
WebSocket的连接包括第一步握手和第二步数据交换。在通过WebSocket开始双向通信时,首先需要与服务器建立连接。而用于建立连接的请求是由客户端发起,服务器端将会确认连接对象的源以及协议,并发送连接许可的响应。在发送了响应之后,浏览器会将该连接升级为WebSocket。握手成功之后就建立起长连接,直到服务器或者浏览器某一方主动断开连接。客户端发起连接非常简单,只需要一句Javascript即可实现:

var ws = new WebSocket('ws://www.example.com/bar')

然后就是第二步,浏览器和服务器之间双向数据发送了。Nodejs是即时通信应用很完美的开发语言(此处不是为了引起撕逼),很自然地,Nodejs本身也比较完善地实现了WebSocket相关API。客户端(浏览器)发送消息到服务器最简单的方法就是通过调用socket对象的send()方法,然后Node服务器通过注册message事件进行监听,当然服务器send过来的消息也是通过对客户端message事件进行捕捉,从而实现双向的数据交互。这两者之间交换的数据可以是字符串、ArrayBuffer(二进制数据)或者Blob,所以WebSocket也是可以传输文件的。也可以通过广播事件将消息发送到所有连接到服务器的客户端。


使用框架:Java-WebSocket

Gradle

To use Gradle add the maven central repository to your repositories list :

mavenCentral()

Then you can just add the latest version to your build.

compile "org.java-websocket:Java-WebSocket:1.3.8"

Client Example


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_6455;
import org.java_websocket.handshake.ServerHandshake;

public class EmptyClient extends WebSocketClient {

	public EmptyClient(URI serverUri, Draft draft) {
		super(serverUri, draft);
	}

	public EmptyClient(URI serverURI) {
		super(serverURI);
	}

	@Override
	public void onOpen(ServerHandshake handshakedata) {
		send("Hello, it is me. Mario :)");
		System.out.println("new connection opened");
	}

	@Override
	public void onClose(int code, String reason, boolean remote) {
		System.out.println("closed with exit code " + code + " additional info: " + reason);
	}

	@Override
	public void onMessage(String message) {
		System.out.println("received message: " + message);
	}

	@Override
	public void onMessage(ByteBuffer message) {
		System.out.println("received ByteBuffer");
	}

	@Override
	public void onError(Exception ex) {
		System.err.println("an error occurred:" + ex);
	}

	public static void main(String[] args) throws URISyntaxException {		
		WebSocketClient client = new EmptyClient(new URI("ws://localhost:8887"));
		client.connect();
	}
}

Server Example

import java.net.InetSocketAddress;

import org.java_websocket.WebSocket;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;

public class SimpleServer extends WebSocketServer {

	public SimpleServer(InetSocketAddress address) {
		super(address);
	}

	@Override
	public void onOpen(WebSocket conn, ClientHandshake handshake) {
		conn.send("Welcome to the server!"); //This method sends a message to the new client
		broadcast( "new connection: " + handshake.getResourceDescriptor() ); //This method sends a message to all clients connected
		System.out.println("new connection to " + conn.getRemoteSocketAddress());
	}

	@Override
	public void onClose(WebSocket conn, int code, String reason, boolean remote) {
		System.out.println("closed " + conn.getRemoteSocketAddress() + " with exit code " + code + " additional info: " + reason);
	}

	@Override
	public void onMessage(WebSocket conn, String message) {
		System.out.println("received message from "	+ conn.getRemoteSocketAddress() + ": " + message);
	}

	@Override
	public void onMessage( WebSocket conn, ByteBuffer message ) {
		System.out.println("received ByteBuffer from "	+ conn.getRemoteSocketAddress());
	}

	@Override
	public void onError(WebSocket conn, Exception ex) {
		System.err.println("an error occured on connection " + conn.getRemoteSocketAddress()  + ":" + ex);
	}
	
	@Override
	public void onStart() {
		System.out.println("server started successfully");
	}


	public static void main(String[] args) {
		String host = "localhost";
		int port = 8887;

		WebSocketServer server = new SimpleServer(new InetSocketAddress(host, port));
		server.run();
	}
}

还有一个封装框架挺好:RxWebSocket

how to use

添加依赖:

在项目module下gradle加入:


	//本项目
	compile 'com.dhh:websocket:1.5.0'
	

init


        //if you want to use your okhttpClient
        OkHttpClient yourClient = new OkHttpClient();
        RxWebSocketUtil.getInstance().setClient(yourClient);
		// show log,default false
        RxWebSocketUtil.getInstance().setShowLog(true);

WSS support,其实就是设置okhttp的SSL,请参照okhttp的设置


        //wss support
        RxWebSocketUtil.getInstance().setSSLSocketFactory(yourSSlSocketFactory,yourX509TrustManager);
        RxWebSocketUtil.getInstance().getWebSocket("wss://...");
        //or
        OkHttpClient client = new OkHttpClient.Builder()
                .sslSocketFactory(yourSSlSocketFactory, yourX509TrustManager)
                //other config...
                .build();
        RxWebSocketUtil.getInstance().setClient(client);

open WebSocket


	RxWebSocketUtil.getInstance().getWebSocketInfo(url)
	                        .subscribe(new Action1<WebSocketInfo>() {
	                            @Override
	                            public void call(WebSocketInfo webSocketInfo) {
	                                mWebSocket = webSocketInfo.getWebSocket();
	                                Log.d("MainActivity", webSocketInfo.getString());
	                                Log.d("MainActivity", "webSocketInfo.getByteString():" + webSocketInfo.getByteString());
	                            }
	                        });
	
	mWebSocket.send("hello word");

        // use WebSocketSubscriber
        RxWebSocketUtil.getInstance().getWebSocketInfo("ws://10.7.5.88:8089")
                //RxLifecycle : https://github.com/dhhAndroid/RxLifecycle
                .compose(RxLifecycle.with(this).<WebSocketInfo>bindOnDestroy())
                .subscribe(new WebSocketSubscriber() {
                    @Override
                    public void onOpen(@NonNull WebSocket webSocket) {

                    }

                    @Override
                    public void onMessage(@NonNull String text) {

                    }

                    @Override
                    public void onMessage(@NonNull ByteString bytes) {

                    }
                });
        // use WebSokcetAction1
        RxWebSocketUtil.getInstance().getWebSocketInfo("ws://10.7.5.88:8089")
                //RxLifecycle : https://github.com/dhhAndroid/RxLifecycle
                .compose(RxLifecycle.with(this).<WebSocketInfo>bindOnDestroy())
                .subscribe(new WebSokcetAction1() {
                    @Override
                    public void onOpen(@NonNull WebSocket webSocket) {

                    }

                    @Override
                    public void onMessage(@NonNull String text) {

                    }

                    @Override
                    public void onMessage(@NonNull ByteString bytes) {

                    }
                });

    //get StringMsg
    RxWebSocketUtil.getInstance().getWebSocketString(url)
            .subscribe(new Action1<String>() {
                @Override
                public void call(String s) {
                }
            });
    // get ByteString
    RxWebSocketUtil.getInstance().getWebSocketByteString(url)
            .subscribe(new Action1<ByteString>() {
                @Override
                public void call(ByteString byteString) {

                }
            });
    //get WebSocket
    RxWebSocketUtil.getInstance().getWebSocket(url)
            .subscribe(new Action1<WebSocket>() {
                @Override
                public void call(WebSocket webSocket) {

                }
            });
	//with timeout
    RxWebSocketUtil.getInstance().getWebSocketInfo(url, 10, TimeUnit.SECONDS)
            .subscribe(new Action1<WebSocketInfo>() {
                @Override
                public void call(WebSocketInfo webSocketInfo) {

                }
            });

	// Rxbinding
    RxView.clicks(centect)
            .flatMap(new Func1<Void, Observable<String>>() {
                @Override
                public Observable<String> call(Void aVoid) {
                    return RxWebSocketUtil.getInstance().getWebSocketString(url);
                }
            })
            .subscribe(new Action1<String>() {
                @Override
                public void call(String s) {
                    //the s !=null

                    Log.d("MainActivity", s);
                    textview.setText(Html.fromHtml(s));

                }
            });

发送消息


	  //用WebSocket的引用直接发
	  mWebSocket.send("hello word");
	
	  //url 对应的WebSocket已经打开可以这样send,否则报错
	  RxWebSocketUtil.getInstance().send(url, "hello");
	  RxWebSocketUtil.getInstance().send(url, ByteString.EMPTY);
	
	  //异步发送,若WebSocket已经打开,直接发送,若没有打开,打开一个WebSocket发送完数据,直接关闭.
	  RxWebSocketUtil.getInstance().asyncSend(url, "hello");
	  RxWebSocketUtil.getInstance().asyncSend(url, ByteString.EMPTY);

注销

RxJava的注销方式,就可以取消订阅. 项目里的demo里,简单实现了一个Lifecycle.仅供参考.


    Subscription subscription = RxWebSocketUtil.getInstance().getWebSocketString("ws://sdfs").subscribe();
	//注销
    if(subscription!=null&&!subscription.isUnsubscribed()) {
        subscription.unsubscribe();
    }


网友评论

登录后评论
0/500
评论
sealin
+ 关注