Android 源码系列之<十六>,深入浅出WebSocket,打造自己的即时聊天交互系统<下>

       转载请注明出处:http://blog.csdn.net/llew2011/article/details/72987090

       在上篇文章Android 源码系列之<十五>,深入浅出WebSocket,打造自己的即时聊天交互系统<上>中主要讲解了WebSocket协议,然后通过实战方式展示了WebSocket的通信过程,这篇文章我将从源码的角度带领小伙伴们深入理解一下autobahn以及okhttp的Socket通信源码,如果你对上述项目的WebSocket实现比较清楚了,请跳过本文(*^__^*) ……

        我们首先从GitHub上clone来下autobahn的源码,运行一下该项目,效果如下:       


       autobahn给出的demo我稍微做了修改,IP和端口号是我从网上找的一个在线测试地址,当点击Connect按钮后就会链接输入框给定的IP地址和端口号,然后进行链接操作,链接成功后通过Toast弹出服务器端返回的消息,表示Socket链接已经建立,可以进行通信了,然后我们可以在下方的输入框中输入任意内容给服务器,为了弄清楚通信过程,我们通过分析点击Connect按钮看看发生的流程,点击CONNECT按钮会调用start()方法,源码如下:

private void start() {

    final String wsuri = "ws://" + mHostname.getText() + ":" + mPort.getText();

    mStatusline.setText("Status: Connecting to " + wsuri + " ..");

    setButtonDisconnect();

    try {
        mConnection.connect(wsuri, new WebSocketConnectionHandler() {
            @Override
            public void onOpen() {
                mStatusline.setText("Status: Connected to " + wsuri);
                savePrefs();
                mSendMessage.setEnabled(true);
                mMessage.setEnabled(true);
            }

            @Override
            public void onTextMessage(String payload) {
                alert("Got echo: " + payload);
                Log.e("---WebSocket---", payload);
            }

            @Override
            public void onClose(int code, String reason) {
                alert("Connection lost.");
                mStatusline.setText("Status: Ready.");
                setButtonConnect();
                mSendMessage.setEnabled(false);
                mMessage.setEnabled(false);
            }
        });
    } catch (WebSocketException e) {
        Log.d(TAG, e.toString());
    }
}
       start()方法就是进行链接Socket的核心,首先根据输入框输入的IP地址和端口生成一个wsuri地址(该处值为:ws://121.40.165.18:8088),然后设置Connect按钮为不可点击状态,最后通过mConnection的connect()方法进行Socket链接,mConnection的定义如下:
private final WebSocket mConnection = new WebSocketConnection();
       mConnection是WebSocket类型,该类是抽象类,它的实现类是WebSocketConnection,那也就是说mConnection调用的connect()方法走的是WebSocketConnection的connect()方法,其源码如下:
public void connect(String wsUri, WebSocket.ConnectionHandler wsHandler) throws WebSocketException {
    connect(wsUri, null, wsHandler, new WebSocketOptions(), null);
}
       connect()方法又调用了其重载方法connect(),源码如下:
public void connect(String wsUri, String[] wsSubprotocols, WebSocket.ConnectionHandler wsHandler, WebSocketOptions options, List<BasicNameValuePair> headers) throws WebSocketException {
    // don't connect if already connected .. user needs to disconnect first
    if (isConnected()) {
        throw new WebSocketException("already connected");
    }
    // parse WebSockets URI
    try {
        mWsUri = new URI(wsUri);

        if (!mWsUri.getScheme().equals("ws") && !mWsUri.getScheme().equals("wss")) {
            throw new WebSocketException("unsupported scheme for WebSockets URI");
        }

        mWsScheme = mWsUri.getScheme();

        if (mWsUri.getPort() == -1) {
            if (mWsScheme.equals("ws")) {
                mWsPort = 80;
            } else {
                mWsPort = 443;
            }
        } else {
            mWsPort = mWsUri.getPort();
        }

        if (mWsUri.getHost() == null) {
            throw new WebSocketException("no host specified in WebSockets URI");
        } else {
            mWsHost = mWsUri.getHost();
        }

        if (mWsUri.getRawPath() == null || mWsUri.getRawPath().equals("")) {
            mWsPath = "/";
        } else {
            mWsPath = mWsUri.getRawPath();
        }

        if (mWsUri.getRawQuery() == null || mWsUri.getRawQuery().equals("")) {
            mWsQuery = null;
        } else {
            mWsQuery = mWsUri.getRawQuery();
        }
    } catch (URISyntaxException e) {
        throw new WebSocketException("invalid WebSockets URI");
    }

    mWsSubprotocols = wsSubprotocols;
    mWsHeaders = headers;
    mWsHandler = wsHandler;

    // make copy of options!
    mOptions = new WebSocketOptions(options);

    // set connection active
    mActive = true;

    // reset value
    onCloseCalled = false;

    // use async connector on short-lived background thread
    new WebSocketConnector().start();
}
       该方法首先判断链接是否建立,如果建立则直接抛了一个异常,因为链接一旦建立了就不需要再次建立,然后检测给定的URI协议和端口是否符合规范,如果都符合WebSocket协议规范则启动后台线程WebSocketConnector来进行消息通信,该类源码如下:
/**
 * Asynchronous socket connector.
 */
private class WebSocketConnector extends Thread {

    publi
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值