⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 impsconnection.java

📁 Android平台上即时通讯聊天工具源代码。 支持手机聊天。
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
            mCirChannel = null;        }        LogoutCompletion logoutCompletion = new LogoutCompletion();        AsyncTransaction tx = new SimpleAsyncTransaction(mTransactionManager,                logoutCompletion);        Primitive logoutPrimitive = new Primitive(ImpsTags.Logout_Request);        tx.sendRequest(logoutPrimitive);    }    // We cannot shut down our connections in ImpsAsyncTransaction.onResponse()    // because at that time the logout transaction itself hasn't ended yet. So    // we have to do this in this completion object.    class LogoutCompletion implements AsyncCompletion {        public void onComplete() {            shutdown();        }        public void onError(ImErrorInfo error) {            // We simply ignore all errors when logging out.            // NowIMP responds a <Disconnect> instead of <Status> on logout request.            shutdown();        }    }    public ImpsSession getSession() {        return mSession;    }    @Override    public Contact getLoginUser() {        if(mSession == null){            return null;        }        Contact loginUser = mSession.getLoginUser();        loginUser.setPresence(getUserPresence());        return loginUser;    }    @Override    public int[] getSupportedPresenceStatus() {        return mConfig.getPresenceMapping().getSupportedPresenceStatus();    }    public ImpsTransactionManager getTransactionManager() {        return mTransactionManager;    }    @Override    public ChatSessionManager getChatSessionManager() {        return mChatSessionManager;    }    @Override    public ContactListManager getContactListManager() {        return mContactListManager;    }    @Override    public ChatGroupManager getChatGroupManager() {        return mChatGroupManager;    }    /**     * Sends a specific primitive to the server. It will return immediately     * after the primitive has been put to the sending queue.     *     * @param primitive the packet to send.     */    void sendPrimitive(Primitive primitive) {        mDataChannel.sendPrimitive(primitive);    }    /**     * Sends a PollingRequest to the server.     */    void sendPollingRequest() {        Primitive pollingRequest = new Primitive(ImpsTags.Polling_Request);        pollingRequest.setSession(getSession().getID());        mDataChannel.sendPrimitive(pollingRequest);    }    private void initDataChannel() throws ImException {        TransportType dataChannelBinding = mConfig.getDataChannelBinding();        if (dataChannelBinding == TransportType.HTTP) {            mDataChannel = new HttpDataChannel(this);        } else {            throw new ImException("Unsupported data channel binding");        }    }    void setupCIRChannel() throws ImException {        if(mConfig.getDataChannelBinding() == TransportType.SMS) {            // No CIR channel is needed, do nothing.            return;        }        CirMethod cirMethod = mSession.getCurrentCirMethod();        if (cirMethod == null) {            cirMethod = mConfig.getCirChannelBinding();            if (!mSession.getSupportedCirMethods().contains(cirMethod)) {                // Sever don't support the CIR method                cirMethod = CirMethod.SHTTP;            }            mSession.setCurrentCirMethod(cirMethod);        }        if (cirMethod == CirMethod.SHTTP) {            mCirChannel = new HttpCirChannel(this, mDataChannel);        } else if (cirMethod == CirMethod.STCP) {            mCirChannel = new TcpCirChannel(this);        } else if (cirMethod == CirMethod.NONE) {            //Do nothing        } else {            throw new ImException(ImErrorInfo.UNSUPPORTED_CIR_CHANNEL,                    "Unsupported CIR channel binding");        }        if(mCirChannel != null) {            mCirChannel.connect();        }    }    private class PrimitiveDispatcherThread extends Thread {        private boolean stopped;        private DataChannel mChannel;        public PrimitiveDispatcherThread(DataChannel channel)        {            super("ImpsPrimitiveDispatcher");            mChannel = channel;        }        @Override        public void run() {            Primitive primitive = null;            while (!stopped) {                try {                    primitive = mChannel.receivePrimitive();                } catch (InterruptedException e) {                    if (stopped) {                        break;                    }                    primitive = null;                }                if (primitive != null) {                    try {                        processIncomingPrimitive(primitive);                    } catch (Throwable t) {                        // We don't know what is going to happen in the various                        // listeners.                        ImpsLog.logError("ImpsDispatcher: uncaught Throwable", t);                    }                }            }        }        void shutdown() {            stopped = true;            interrupt();        }    }    /**     * Handles the primitive received from the server.     *     * @param primitive the received primitive.     */    void processIncomingPrimitive(Primitive primitive) {        // if CIR is 'F', the CIR channel is not available. Re-establish it.        if (primitive.getCir() != null && ImpsUtils.isFalse(primitive.getCir())) {            if(mCirChannel != null) {                mCirChannel.shutdown();            }            try {                setupCIRChannel();            } catch (ImException e) {                e.printStackTrace();            }        }        if (primitive.getPoll() != null && ImpsUtils.isTrue(primitive.getPoll())) {            sendPollingRequest();        }        if (primitive.getType().equals(ImpsTags.Disconnect)) {            if (mState != LOGGING_OUT) {                ImErrorInfo error = ImpsUtils.checkResultError(primitive);                shutdownOnError(error);                return;            }        }        // According to the IMPS spec, only VersionDiscoveryResponse which        // are not supported now doesn't have a transaction ID.        if (primitive.getTransactionID() != null) {            mTransactionManager.notifyIncomingPrimitive(primitive);        }    }    @Override    protected void doUpdateUserPresenceAsync(Presence presence) {        ArrayList<PrimitiveElement> presenceSubList = ImpsPresenceUtils.buildUpdatePresenceElems(                mUserPresence, presence, mConfig.getPresenceMapping());        Primitive request = buildUpdatePresenceReq(presenceSubList);        // Need to make a copy because the presence passed in may change        // before the transaction finishes.        final Presence newPresence = new Presence(presence);        AsyncTransaction tx = new AsyncTransaction(mTransactionManager) {            @Override            public void onResponseOk(Primitive response) {                savePresenceChange(newPresence);                notifyUserPresenceUpdated();            }            @Override            public void onResponseError(ImpsErrorInfo error) {                notifyUpdateUserPresenceError(error);            }        };        tx.sendRequest(request);    }    void savePresenceChange(Presence newPresence) {        mUserPresence.setStatusText(newPresence.getStatusText());        mUserPresence.setStatus(newPresence.getStatus());        mUserPresence.setAvatar(newPresence.getAvatarData(), newPresence.getAvatarType());        // no need to update extended info because it's always read only.    }    void retrieveUserPresenceAsync(final AsyncCompletion completion) {        Primitive request = new Primitive(ImpsTags.GetPresence_Request);        request.addElement(this.getSession().getLoginUserAddress().toPrimitiveElement());        AsyncTransaction tx = new AsyncTransaction(mTransactionManager){            @Override            public void onResponseOk(Primitive response) {                PrimitiveElement presence = response.getElement(ImpsTags.Presence);                PrimitiveElement presenceSubList = presence.getChild(ImpsTags.PresenceSubList);                mUserPresence = ImpsPresenceUtils.extractPresence(presenceSubList,                        mConfig.getPresenceMapping());                // XXX: workaround for the OZ IMPS GTalk server that                // returns an initial 'F' OnlineStatus. Set the online                // status to available in this case.                if(mUserPresence.getStatus() == Presence.OFFLINE) {                    mUserPresence.setStatus(Presence.AVAILABLE);                }                compareAndUpdateClientInfo();            }            @Override            public void onResponseError(ImpsErrorInfo error) {                mUserPresence = new Presence(Presence.AVAILABLE, "", null,                        null, Presence.CLIENT_TYPE_MOBILE, ImpsUtils.getClientInfo());                completion.onError(error);            }            private void compareAndUpdateClientInfo() {                if (!ImpsUtils.getClientInfo().equals(mUserPresence.getExtendedInfo())) {                    updateClientInfoAsync(completion);                    return;                }                // no need to update our client info to the server again                completion.onComplete();            }        };        tx.sendRequest(request);    }    void updateClientInfoAsync(AsyncCompletion completion) {        Primitive updatePresenceRequest = buildUpdatePresenceReq(buildClientInfoElem());        AsyncTransaction tx = new SimpleAsyncTransaction(mTransactionManager,                completion);        tx.sendRequest(updatePresenceRequest);    }    private Primitive buildUpdatePresenceReq(PrimitiveElement presence) {        ArrayList<PrimitiveElement> presences = new ArrayList<PrimitiveElement>();        presences.add(presence);        return buildUpdatePresenceReq(presences);    }    private Primitive buildUpdatePresenceReq(ArrayList<PrimitiveElement> presences) {        Primitive updatePresenceRequest = new Primitive(ImpsTags.UpdatePresence_Request);        PrimitiveElement presenceSubList = updatePresenceRequest                .addElement(ImpsTags.PresenceSubList);        presenceSubList.setAttribute(ImpsTags.XMLNS, mConfig.getPresenceNs());        for (PrimitiveElement presence : presences) {            presenceSubList.addChild(presence);        }        return updatePresenceRequest;    }    private PrimitiveElement buildClientInfoElem() {        PrimitiveElement clientInfo = new PrimitiveElement(ImpsTags.ClientInfo);        clientInfo.addChild(ImpsTags.Qualifier, true);        Map<String, String> map = ImpsUtils.getClientInfo();        for (Map.Entry<String, String> item : map.entrySet()) {            clientInfo.addChild(item.getKey(), item.getValue());        }        return clientInfo;    }    Primitive buildBasicLoginReq() {        Primitive login = new Primitive(ImpsTags.Login_Request);        login.addElement(ImpsTags.UserID, mSession.getUserName());        PrimitiveElement clientId = login.addElement(ImpsTags.ClientID);        clientId.addChild(ImpsTags.URL, mConfig.getClientId());        if (mConfig.getMsisdn() != null) {            clientId.addChild(ImpsTags.MSISDN, mConfig.getMsisdn());        }        // we request for a bigger TimeToLive value than our default keep        // alive interval to make sure we always have time to send the keep        // alive requests.        login.addElement(ImpsTags.TimeToLive,                Integer.toString(mConfig.getDefaultKeepAliveInterval() + 5));        login.addElement(ImpsTags.SessionCookie, mSession.getCookie());        return login;    }    @Override    synchronized public void suspend() {        setState(SUSPENDING, null);        if (mCirChannel != null) {            mCirChannel.shutdown();        }        if (mDispatcherThread != null) {            mDispatcherThread.shutdown();        }        if (mDataChannel != null) {            mDataChannel.shutdown();        }        setState(SUSPENDED, null);    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -