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

📄 httpdatachannel.java

📁 Android平台上即时通讯聊天工具源代码。 支持手机聊天。
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* * 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.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.URI;import java.net.URISyntaxException;import java.util.concurrent.LinkedBlockingQueue;import java.util.concurrent.TimeUnit;import java.util.concurrent.atomic.AtomicBoolean;import org.apache.http.Header;import org.apache.http.HttpEntity;import org.apache.http.HttpResponse;import org.apache.http.StatusLine;import org.apache.http.client.methods.HttpPost;import org.apache.http.entity.ByteArrayEntity;import org.apache.http.message.BasicHeader;import org.apache.http.params.HttpConnectionParams;import org.apache.http.params.HttpParams;import android.net.http.AndroidHttpClient;import android.os.SystemClock;import android.util.Log;import com.android.im.engine.ImErrorInfo;import com.android.im.engine.ImException;import com.android.im.imps.Primitive.TransactionMode;/** * The <code>HttpDataChannel</code> is an implementation of IMPS data channel * in which the protocol binding is HTTP. */class HttpDataChannel extends DataChannel implements Runnable {    private static final int MAX_RETRY_COUNT = 10;    private static final int INIT_RETRY_DELAY_MS = 5000;    private static final int MAX_RETRY_DELAY_MS = 300 * 1000;    private Thread mSendThread;    private boolean mStopped;    private boolean mConnected;    private boolean mStopRetry;    private Object mRetryLock = new Object();    private LinkedBlockingQueue<Primitive> mSendQueue;    private LinkedBlockingQueue<Primitive> mReceiveQueue;    private long mLastActive;    private int mKeepAliveMillis;    private Primitive mKeepAlivePrimitive;    private AtomicBoolean mHasPendingPolling = new AtomicBoolean(false);    private final AndroidHttpClient mHttpClient;    private final Header mContentTypeHeader;    private final Header mMsisdnHeader;    private URI mPostUri;    private ImpsTransactionManager mTxManager;    /**     * Constructs a new HttpDataChannel for a connection.     *     * @param connection the connection which uses the data channel.     */    public HttpDataChannel(ImpsConnection connection) throws ImException {        super(connection);        mTxManager = connection.getTransactionManager();        ImpsConnectionConfig cfg = connection.getConfig();        try {            mPostUri = new URI(cfg.getHost());            if (mPostUri.getPath() == null || "".equals(mPostUri.getPath())) {                mPostUri = new URI(cfg.getHost() + "/");            }            if (!"http".equalsIgnoreCase(mPostUri.getScheme())                    && !"https".equalsIgnoreCase(mPostUri.getScheme())) {                throw new ImException(ImErrorInfo.INVALID_HOST_NAME,                        "Non HTTP/HTTPS host name.");            }            mHttpClient = AndroidHttpClient.newInstance("Android-Imps/0.1");            HttpParams params = mHttpClient.getParams();            HttpConnectionParams.setConnectionTimeout(params, cfg.getReplyTimeout());            HttpConnectionParams.setSoTimeout(params, cfg.getReplyTimeout());        } catch (URISyntaxException e) {            throw new ImException(ImErrorInfo.INVALID_HOST_NAME,                    e.getLocalizedMessage());        }        mContentTypeHeader = new BasicHeader("Content-Type", cfg.getTransportContentType());        String msisdn = cfg.getMsisdn();        mMsisdnHeader = (msisdn != null) ? new BasicHeader("MSISDN", msisdn) : null;    }    @Override    public void connect() throws ImException {        if (mConnected) {            throw new ImException("Already connected");        }        mStopped = false;        mStopRetry = false;        mSendQueue = new LinkedBlockingQueue<Primitive>();        mReceiveQueue = new LinkedBlockingQueue<Primitive>();        mSendThread = new Thread(this, "HttpDataChannel");        mSendThread.setDaemon(true);        mSendThread.start();        mConnected = true;    }    @Override    public void shutdown() {        // Stop the sending thread        mStopped = true;        mSendThread.interrupt();        mConnected = false;    }    @Override    public void sendPrimitive(Primitive p) {        if (!mConnected || mStopped) {            ImpsLog.log("DataChannel not connected, ignore primitive " + p.getType());            return;        }        if (ImpsTags.Polling_Request.equals(p.getType())) {            if (!mHasPendingPolling.compareAndSet(false, true)) {                ImpsLog.log("HttpDataChannel: Ignoring Polling-Request");                return;            }        } else if (ImpsTags.Logout_Request.equals(p.getType())) {            mStopRetry = true;            synchronized (mRetryLock) {                mRetryLock.notify();            }        }        if (!mSendQueue.offer(p)) {            // This is almost impossible for a LinkedBlockingQueue. We don't            // even bother to assign an error code for this. ;)            mTxManager.notifyErrorResponse(p.getTransactionID(),                    ImErrorInfo.UNKNOWN_ERROR, "sending queue full");        }    }    @Override    public Primitive receivePrimitive() throws InterruptedException {        if (!mConnected || mStopped) {            throw new IllegalStateException();        }        return mReceiveQueue.take();    }    @Override    public void startKeepAlive(long interval) {        if (!mConnected || mStopped) {            throw new IllegalStateException();        }        if (interval <= 0) {            interval = mConnection.getConfig().getDefaultKeepAliveInterval();        }        mKeepAliveMillis = (int)(interval * 1000 - 100);        if (mKeepAliveMillis < 0) {            ImpsLog.log("Negative keep alive time. Won't send keep-alive");        }        mKeepAlivePrimitive = new Primitive(ImpsTags.KeepAlive_Request);    }    @Override    public long getLastActiveTime() {        return mLastActive;    }    @Override    public boolean isSendingQueueEmpty() {        if (!mConnected || mStopped) {            throw new IllegalStateException();        }        return mSendQueue.isEmpty();    }    public void run() {        boolean needKeepAlive = false;        while (!mStopped) {            if (needKeepAlive) {                sendKeepAlive();                needKeepAlive = false;            }            Primitive primitive;

⌨️ 快捷键说明

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