网络流程的梳理

在微信登陆成功之后把微信返回的code通过Autorize类的sendWXLoginAuther方法将这个code传给我们自己的后台

这里开始详细讲Autorize类。这个类至关重要

上文讲到Autorize类的sendWXLoginAuther方法,这个方法里里面将调用内部的两个方法,一个

private void startAuthorize(String authCode) {

prepareAuthorize();

mConnector.openConnection(authCode);

}

这两个方法,第一个是

private void prepareAuthorize() {
        NetworkEngineUtils.prepareEngine(mHosts);
    }

这个是准备NetworkEngine
最终prepareEngin的实现是

    public static void prepareEngine(NetworkAddress[] hosts, long ssoPresent, String key) {
        if (key == null) key = DEFAULT_KEY;

        NetworkEngine.shareEngine().setDefultkey(ssoPresent, StringHelper.getUtf8Code(key));

        String[] ips = new String[hosts.length];
        int[] port = new int[hosts.length];
        NetworkAddress.split(hosts, ips, port);

        NetworkEngine.shareEngine().setHosts(NetworkEngine.CONN_TYPE_DIR, ips, port);
    }
NetworkEngine.shareEngine().setDefultkey(ssoPresent, StringHelper.getUtf8Code(key));

这句代码得分几步看

  1. shareEngine(),这里初始化了一个JAVA层的NetWorkEngine,这个NetWorkEngine在初始化的时候调用native_create同时初始化c++层的NetWorkEngin—在engine_jni.cpp文件可以找到
  2. setDefultkey,将参数设置进C++层的NetWorkEngine—–在engine_jni.cpp文件可以找到

    NetworkEngine.shareEngine().setHosts(NetworkEngine.CONN_TYPE_DIR, ips, port);
    这句代码则是设置host,也就是ip地址

    public void setHosts(int type, String[] hosts, int[] ports)
    {
        try
        {
            native_set_hosts(type, hosts, ports);
        }
        catch (UnsatisfiedLinkError e)
        {

        }
    }

可以看到在NetWorkEngine中直接就调用了native方法,这里就到了C++层,这个native_set_hosts在c++层最终调用的是C++的NetworkEngine的set_host_list方法
看实现

    void set_host_list(int type, const std::vector<std::string> &hosts, const std::vector<int> &ports)
    {
        qt_base::CritScope cs(&crit_);
        Channel *ch = getAndCreateChannel(type);
        if (ch != NULL) {
            ch->set_host_list(hosts, ports);
        }
    }

从实现中可以看出,C++层的NetWorkEngine在收到ip之后,第一步是创建了一个Channel,然后把ip传给了channel,
转看Channel的这个set方法

    void set_host_list(const std::vector<std::string> &hosts, const std::vector<int> &ports)
    {
        hosts_.clear();
        ports_.clear();

        hosts_ = hosts;
        ports_ = ports;

        if (conn_ != NULL && !hosts.empty() && !ports.empty())
        {
            conn_->SetHostList(hosts_, ports_);
        }
    }

Channel又有一个关键的属性,那就是connector,也就是这conn_,在network\jni\network目录下,真正的连接都是在这里,包括超时时间等.而这个connector有一个SendRequest方法,这个SendRequest又是调用了protocolDriver的SendRequest方法,而protocolDriver持有一个IOLooper,这个是消息队列,所谓protocolDriver的sendRequest也就是把request放到了IOLooper这个消息队列中,IOLooper这个队列里面会自己开启一个线程去不断的执行网络请求,并且把返回向上回调回去,也就是我们在java层最终收到的listener(或则叫callBack也行)

发送正常请求流程

从Resolver看起
一个resolver的sendRequest调用的是基类ProtoMessager的sendRequest方法,这个方法其实调用的就是PBSender的sendRequest操作,看PBSender的这个方法的实现

 public void sendRequest(PBRequest<PARAM> request, OnPBSenderListener<PARAM> listener){
        ALog.i(TAG, "in sendRequest: request=" + request);
        request.listener = listener;
        request.requestTimeMillis = System.currentTimeMillis();
        enqueueRequest(request);
        checkForSend(true);
    }

看这个方法的两句,第一enqueueRequest,这个是把request放入到mSendQueue这个消息队列里面,第二句checkForSend(true),这个代码最终跑到了startSendRequests,然后就跑到了 sendOutRequestLocked,看实现

private void sendOutRequestLocked(){
        PBRequest request;
        while ((request = mSendQueue.poll()) != null){

            if (request.isCanceled){
                ALog.i(TAG, "request already canceled:" + request);
                continue;
            }

            if (!request.isPreviousConnectRequest) {
                sendRequestInner(request);
            } else {  //预留游客模式的情况
                boolean isBoundCurrenly = (mLoginState.getAuthType() != null && mLoginState.getAuthType() != AuthType.Tourist);

            }
        }
    }

注意这是一个死循环,到目前为止也就是说,一个PBSender就维护了一个消息队列,自己跑了一个死循环来发送里面的所有请求,而里面每一个请求都会跑sendRequestInner这个方法,看实现

    private void sendRequestInner(PBRequest request){

        int command = request.command;
        int subcmd = request.subcmd;

        byte[] payload = request.listener.onBuildRequestData(request, mLoginState);
        if (payload == null){
            ALog.i(TAG, "onBuildRequestData returned null, request=" + request);
        }

        ALog.i(TAG, "sendRequestInner: request=" + request);
        int timeout = mAuthWaitMillis > 0 ? mAuthWaitMillis : NetworkEngine.DEFAULT_TIMEOUT;
        int result = NetworkEngine.shareEngine().sendRequest(command, subcmd, payload, new ProtoBufferMessageHandler(request), timeout);
        if (result == -1){
            if (request.listener != null)
                request.listener.onError(request, ErrorFactoryPb.NETWORK_INVALID);

            return;
        }

        addToWaitList(request);
    }

看到这里,一切都豁然开朗了,因为这个时候又出现了NetworkEngine,看这个sendRequest是干了什么

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值