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

📄 tcpcirchannel.java

📁 Android平台上即时通讯聊天工具源代码。 支持手机聊天。
💻 JAVA
字号:
/* * Copyright (C) 2007-2008 Esmertec AG. * Copyright (C) 2007-2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.android.im.imps;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.net.Socket;import java.net.UnknownHostException;import java.util.Vector;import com.android.im.engine.ImErrorInfo;import com.android.im.engine.ImException;import android.os.SystemClock;import android.util.Log;/** * An implementation of CIR channel with standalone TCP/IP banding. */class TcpCirChannel extends CirChannel implements Runnable{    public static final int PING_INTERVAL = 20 * 60 * 1000; // 20 min    private static final int OK_TIMEOUT = 30000;    private String mAddress;    private int mPort;    private boolean mDone;    private Socket mSocket;    private boolean mWaitForOK;    private long mLastActive;    private String mUser;    private BufferedReader mReader;    private static Vector<TcpCirChannel> sChannels;    static {        sChannels = new Vector<TcpCirChannel>();    }    public static Vector<TcpCirChannel> getChannels(){        return sChannels;    }    protected TcpCirChannel(ImpsConnection connection) {        super(connection);        mAddress = connection.getSession().getCirTcpAddress();        mPort = connection.getSession().getCirTcpPort();        mUser = connection.getSession().getLoginUser().getName();    }    @Override    public synchronized void connect() throws ImException {        try {            connectServer();            sChannels.add(this);            new Thread(this, "TcpCirChannel").start();        } catch (UnknownHostException e) {            throw new ImException(ImErrorInfo.UNKNOWN_SERVER,                    "Can't find the TCP CIR server");        } catch (IOException e) {            throw new ImException(ImErrorInfo.CANT_CONNECT_TO_SERVER,                    "Can't connect to the TCP CIR server");        }    }    @Override    public synchronized void shutdown() {        if (Log.isLoggable(ImpsLog.TAG, Log.DEBUG)) {            ImpsLog.log(mUser + " Shutting down CIR channel");        }        mDone = true;        sChannels.remove(this);        try {            if(mSocket != null) {                mSocket.close();            }        } catch (IOException e) {            e.printStackTrace();        }    }    public void run() {        while (!mDone) {            try {                if (mWaitForOK && SystemClock.elapsedRealtime() - mLastActive                        > OK_TIMEOUT) {                    // OMA-TS-IMPS_CSP_Transport-V1_3-20070123-A 8.1.3:                    // If client doesn't receive an "OK" message or detects                    // that the connection is broken, it MUST open a new                    // TCP/IP connection and send the "HELO" message again.                    connectServer();                }                String line = mReader.readLine();                mLastActive = SystemClock.elapsedRealtime();                if (line == null) {                    // socket closed by the server                    reconnect();                } else if ("OK".equals(line)) {                    mWaitForOK = false;                    if (Log.isLoggable(ImpsLog.TAG, Log.DEBUG)) {                        ImpsLog.log(mUser + " << TCP CIR: OK Received");                    }                    // TODO: Since we just have one thread per TCP CIR                    // connection now, the session cookie is ignored.                } else if (line.startsWith("WVCI")) {                    if (Log.isLoggable(ImpsLog.TAG, Log.DEBUG)) {                        ImpsLog.log(mUser + " << TCP CIR: CIR Received");                    }                    if (!mDone) {                        mConnection.sendPollingRequest();                    }                }            } catch (IOException e) {                ImpsLog.logError("TCP CIR channel get:" + e);                if(!mDone){                    reconnect();                }            }        }        if (mReader != null) {            try {                mReader.close();            } catch (IOException e) {                e.printStackTrace();            }        }        if (Log.isLoggable(ImpsLog.TAG, Log.DEBUG)) {            ImpsLog.log(mUser + " CIR channel thread quit");        }    }    @Override    public void reconnect() {        if (Log.isLoggable(ImpsLog.TAG, Log.DEBUG)) {            ImpsLog.log(mUser + " CIR channel reconnecting");        }        long waitTime = 3000;        while (!mDone) { // Keep trying to connect the server until shutdown            try {                try {                    Thread.sleep(waitTime);                } catch (InterruptedException e) {                }                connectServer();                // Send a polling request to make sure we don't miss anything                // while CIR is down.                if(!mDone) {                    mConnection.sendPollingRequest();                }                return;            } catch (IOException e) {                waitTime *= 3;                if(waitTime > 27000) {                    waitTime = 3000;                    if(!mDone){                        mConnection.sendPollingRequest();                    }                }                if (Log.isLoggable(ImpsLog.TAG, Log.DEBUG)) {                    ImpsLog.log(mUser + " CIR channel reconnect fail, retry after "                        + waitTime / 1000 + " seconds");                }            }        }    }    private synchronized void connectServer() throws IOException {        if(!mDone) {            if (mSocket != null) {                try {                    mSocket.close();                } catch (IOException e) {                    // ignore                }            }            mSocket = new Socket(mAddress, mPort);            if (Log.isLoggable(ImpsLog.TAG, Log.DEBUG)) {                ImpsLog.log(mUser + " >> TCP CIR: HELO");            }            sendData("HELO " + mConnection.getSession().getID() + "\r\n");            if (mReader != null) {                try {                    mReader.close();                } catch (IOException e) {                    // ignore                }            }            mReader = new BufferedReader(                    new InputStreamReader(mSocket.getInputStream(), "UTF-8"),                    8192);        }    }    public synchronized void ping() {        long time = SystemClock.elapsedRealtime();        if(!mDone && time - mLastActive > PING_INTERVAL) {            if (Log.isLoggable(ImpsLog.TAG, Log.DEBUG)) {                ImpsLog.log(mUser + " >> TCP CIR: PING");            }            try {                sendData("PING \r\n");            } catch (IOException e) {                if (Log.isLoggable(ImpsLog.TAG, Log.DEBUG)) {                    ImpsLog.log("Failed to send PING, try to reconnect");                }                reconnect();            }        }    }    private void sendData(String s) throws IOException {        mSocket.getOutputStream().write(s.getBytes("UTF-8"));        mWaitForOK = true;        mLastActive = SystemClock.elapsedRealtime();    }}

⌨️ 快捷键说明

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