您的位置:首页 > 理论基础 > 计算机网络

Http与Socket连接池-java(android)

2016-03-11 18:17 369 查看
》Http连接池

package xiaogang.enif.net;

import java.io.IOException;

import java.net.Socket;

import java.net.UnknownHostException;

import java.security.KeyManagementException;

import java.security.KeyStore;

import java.security.KeyStoreException;

import java.security.NoSuchAlgorithmException;

import java.security.UnrecoverableKeyException;

import java.security.cert.CertificateException;

import java.security.cert.X509Certificate;

import javax.net.ssl.SSLContext;

import javax.net.ssl.TrustManager;

import javax.net.ssl.X509TrustManager;

import org.apache.http.HttpHost;

import org.apache.http.HttpResponse;

import org.apache.http.HttpVersion;

import org.apache.http.client.methods.HttpGet;

import org.apache.http.client.methods.HttpHead;

import org.apache.http.client.methods.HttpPost;

import org.apache.http.client.methods.HttpUriRequest;

import org.apache.http.client.params.HttpClientParams;

import org.apache.http.conn.ClientConnectionManager;

import org.apache.http.conn.params.ConnManagerParams;

import org.apache.http.conn.params.ConnPerRouteBean;

import org.apache.http.conn.params.ConnRouteParams;

import org.apache.http.conn.scheme.PlainSocketFactory;

import org.apache.http.conn.scheme.Scheme;

import org.apache.http.conn.scheme.SchemeRegistry;

import org.apache.http.conn.ssl.SSLSocketFactory;

import org.apache.http.impl.client.DefaultHttpClient;

import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;

import org.apache.http.params.BasicHttpParams;

import org.apache.http.params.HttpConnectionParams;

import org.apache.http.params.HttpParams;

import org.apache.http.params.HttpProtocolParams;

import xiaogang.enif.utils.IOUtils;

import android.content.Context;

import android.net.Proxy;

import android.text.TextUtils;

/**

** 连接池支持http、https;

** 支持wap网络;
*/

public class HttpManager {

private static final int DEFAULT_MAX_CONNECTIONS = 30;

private static final int DEFAULT_SOCKET_TIMEOUT = 20 * 1000;

private static final int DEFAULT_SOCKET_BUFFER_SIZE = 8192;

private static DefaultHttpClient sHttpClient;

static {

final HttpParams httpParams = new BasicHttpParams();

ConnManagerParams.setTimeout(httpParams, 1000);

ConnManagerParams.setMaxConnectionsPerRoute(httpParams, new ConnPerRouteBean(10));

ConnManagerParams.setMaxTotalConnections(httpParams, DEFAULT_MAX_CONNECTIONS);

HttpProtocolParams.setVersion(httpParams, HttpVersion.HTTP_1_1);

HttpProtocolParams.setContentCharset(httpParams, "UTF-8");

HttpConnectionParams.setStaleCheckingEnabled(httpParams, false);

HttpClientParams.setRedirecting(httpParams, false);

HttpProtocolParams.setUserAgent(httpParams, "Android client");

HttpConnectionParams.setSoTimeout(httpParams, DEFAULT_SOCKET_TIMEOUT);

HttpConnectionParams.setConnectionTimeout(httpParams, DEFAULT_SOCKET_TIMEOUT);

HttpConnectionParams.setTcpNoDelay(httpParams, true);

HttpConnectionParams.setSocketBufferSize(httpParams, DEFAULT_SOCKET_BUFFER_SIZE);

SchemeRegistry schemeRegistry = new SchemeRegistry();

schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));

try {

KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());

trustStore.load(null, null);

SSLSocketFactory sf = new MySSLSocketFactory(trustStore);

sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

schemeRegistry.register(new Scheme("https", sf, 443));

} catch (Exception ex) {

// do nothing, just keep not crash

}

ClientConnectionManager manager = new ThreadSafeClientConnManager(httpParams, schemeRegistry);

sHttpClient = new DefaultHttpClient(manager, httpParams);

}

private HttpManager() {

}

public static HttpResponse execute(HttpHead head) throws IOException {

return sHttpClient.execute(head);

}

public static HttpResponse execute(HttpHost host, HttpGet get) throws IOException {

return sHttpClient.execute(host, get);

}

public static HttpResponse execute(Context context, HttpGet get) throws IOException {

if (!IOUtils.isWifiAvailable(context) && isWapNetwork()) {

setWapProxy();

return sHttpClient.execute(get);

}

final HttpHost host = (HttpHost)sHttpClient.getParams().getParameter(

ConnRouteParams.DEFAULT_PROXY);

if (host != null) {

sHttpClient.getParams().removeParameter(ConnRouteParams.DEFAULT_PROXY);

}

return sHttpClient.execute(get);

}

private static void setSinaWapProxy() {

final HttpHost para = (HttpHost)sHttpClient.getParams().getParameter(

ConnRouteParams.DEFAULT_PROXY);

if (para != null) {

sHttpClient.getParams().removeParameter(ConnRouteParams.DEFAULT_PROXY);

}

String host = Proxy.getDefaultHost();

int port = Proxy.getDefaultPort();

HttpHost httpHost = new HttpHost(host, port);

HttpParams httpParams = new BasicHttpParams();

httpParams.setParameter(ConnRouteParams.DEFAULT_PROXY, httpHost);

}

public static HttpResponse execute(Context context, HttpUriRequest post) throws IOException {

if (!IOUtils.isWifiAvailable(context) && isWapNetwork()) {

setSinaWapProxy();

}

return sHttpClient.execute(post);

}

public static HttpResponse execute(Context context, HttpPost post) throws IOException {

if (!IOUtils.isWifiAvailable(context) && isWapNetwork()) {

setWapProxy();

return sHttpClient.execute(post);

}

final HttpHost host = (HttpHost)sHttpClient.getParams().getParameter(

ConnRouteParams.DEFAULT_PROXY);

if (host != null) {

sHttpClient.getParams().removeParameter(ConnRouteParams.DEFAULT_PROXY);

}

return sHttpClient.execute(post);

}

private static boolean isWapNetwork() {

final String proxyHost = android.net.Proxy.getDefaultHost();

return !TextUtils.isEmpty(proxyHost);

}

private static void setWapProxy() {

final HttpHost host = (HttpHost)sHttpClient.getParams().getParameter(

ConnRouteParams.DEFAULT_PROXY);

if (host == null) {

final String host1 = Proxy.getDefaultHost();

int port = Proxy.getDefaultPort();

HttpHost httpHost = new HttpHost(host1, port);

sHttpClient.getParams().setParameter(ConnRouteParams.DEFAULT_PROXY, httpHost);

}

}

private static class MySSLSocketFactory extends SSLSocketFactory {

SSLContext sslContext = SSLContext.getInstance("TLS");

public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException,

KeyManagementException, KeyStoreException, UnrecoverableKeyException {

super(truststore);

TrustManager tm = new X509TrustManager() {

@Override

public void checkClientTrusted(X509Certificate[] chain, String authType)

throws CertificateException {

}

@Override

public void checkServerTrusted(X509Certificate[] chain, String authType)

throws CertificateException {

}

@Override

public X509Certificate[] getAcceptedIssuers() {

return null;

}

};

sslContext.init(null, new TrustManager[] {

tm

}, null);

}

@Override

public Socket createSocket(Socket socket, String host, int port, boolean autoClose)

throws IOException, UnknownHostException {

return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);

}

@Override

public Socket createSocket() throws IOException {

return sslContext.getSocketFactory().createSocket();

}

}

}

》 Socket连接池

1. socet信息类
package cn.richinfo.cloudp.dm.common.util;

import java.net.Socket;

/**
* @Crop 深圳市xxx科技有限公司
* @author liuxingmi
* @QQ 63972012
* @DateTime 2014-8-25 下午3:21:19
* @Desc 名字服务器连接信息
*/
public class SocketInfo {

/**
* socket
*/
private Socket socket;
/**
* 是否空闲 (是:true  否:false)
*/
private boolean isFree;
/**
* socket id
*/
private Integer socketId;

/**
* 是否为可关闭链接 (是:true  否:false)
*/
private boolean isClosed;

public Socket getSocket() {
return socket;
}

public void setSocket(Socket socket) {
this.socket = socket;
}

public boolean isFree() {
return isFree;
}

public void setFree(boolean isFree) {
this.isFree = isFree;
}

public Integer getSocketId() {
return socketId;
}

public void setSocketId(Integer socketId) {
this.socketId = socketId;
}

public boolean isClosed() {
return isClosed;
}

public void setClosed(boolean isClosed) {
this.isClosed = isClosed;
}

}


2. 链接池工具
package cn.richinfo.cloudp.dm.common.util;

import java.io.IOException;
import java.net.Socket;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import cn.richinfo.cloudp.common.config.CloudpConfigUtil;
import cn.richinfo.cloudp.common.constant.ConfigConst;
import cn.richinfo.cloudp.common.log.DMLogger;

/**
* @Crop 深圳市xxxx有限公司
* @author liuxingmi
* @QQ 63972012
* @DateTime 2014-8-25 下午3:18:18
* @Desc 分布式名字服务器socket链接池
*/
public class SocketPool {

private static DMLogger logger = DMLogger.getInstance();//日志类

/**
* socketMap
*/
public static ConcurrentHashMap<Integer, SocketInfo> socketMap = new ConcurrentHashMap<Integer, SocketInfo>();

private static SocketPool instance = new SocketPool();

private SocketPool(){}

public static SocketPool getInstance(){
if(instance == null){
synchronized (SocketPool.class) {
if(instance == null){
instance = new SocketPool();
}
}
}
return instance;
}

static {
instance.initSocket(true);
}

/**
* @DateTime 2014-8-25 下午3:18:52
* @User liuxingmi
* @Desc 初始化链接池
* @param isAllReInit  是否全部重新初始化
* @return void
*/
public  void initSocket(boolean isAllReInit){
int defaultCount = Integer.parseInt(ConfigConst.SOCKET_DEFAULT_COUNT);
logger.info("nameserver:initSocket", DMLogger.RESULT_OK, "开始初始化分布式名字服务器连接数:" + defaultCount);
for (int i = 0; i < defaultCount; i++) {

if(isAllReInit){
socketMap.put(i, setSocketInfo( i, true, false));
} else {
if(socketMap.get(i) == null || socketMap.get(i).isClosed()){
socketMap.put(i, setSocketInfo( i, true, false));
}
}
}

logger.info("nameserver:initSocket", DMLogger.RESULT_OK, "完成初始化分布式名字服务器连接数");
new CheckSocketThread().start();

}

/**
* @DateTime 2014-8-26 上午10:06:13
* @User liuxingmi
* @Desc 设置socketInfo值
* @param socket
* @param key
* @param isFree
* @param isClosed
* @return SocketInfo
*/
private static SocketInfo setSocketInfo(Integer key, boolean isFree, boolean isClosed){
SocketInfo socketInfo = new SocketInfo();
Socket socket = createSocket();
socketInfo.setFree(isFree);
socketInfo.setSocket(socket);
socketInfo.setSocketId(key);
socketInfo.setClosed(isClosed);
return socketInfo;
}

/**
* @DateTime 2014-8-25 下午3:19:06
* @User liuxingmi
* @Desc 获取名字服务器链接
* @return
* SocketInfo
*/
public  SocketInfo getSocketInfo(){

SocketInfo socketInfo = null;

if(socketMap.size() < Integer.parseInt(ConfigConst.SOCKET_DEFAULT_COUNT)){
initSocket(false);
}

if(socketMap.size() > 0){
for (Map.Entry<Integer, SocketInfo> entry : socketMap.entrySet()) {
socketInfo = entry.getValue();
if(socketInfo.isFree() && ! socketInfo.getSocket().isClosed()){
socketInfo.setFree(false);
return socketInfo;
}
}
} else {
logger.info("nameserver:socketInfo", DMLogger.RESULT_FAIL, "名字服务器socket连接池数量为零。");
return null;
}

logger.info("nameserver:socketInfo", DMLogger.RESULT_OK, "所有名字服务器socket链接都忙,创建临时链接。");

socketInfo = setSocketInfo(-1, true, true);
logger.info("nameserver:socketInfo", DMLogger.RESULT_OK, "成功创建服务器socket临时链接。");
return socketInfo;

}

/**
* 释放socket
* @param socketId
*/
public static void distorySocket(Integer socketId){

logger.debug("nameserver:distorySocket", DMLogger.RESULT_OK, "释放名字服务器socket链接。");
SocketInfo socketInfo = socketMap.get(socketId);
socketInfo.setFree(true);

}

/**
* @DateTime 2014-8-25 下午3:19:42
* @User liuxingmi
* @Desc 释放socket
* @param socketInfo
* void
*/
public static void distorySocket(SocketInfo socketInfo){

if(socketInfo == null) return;

if( ! socketInfo.isClosed()){
logger.debug("nameserver:distorySocket", DMLogger.RESULT_OK, "链接池socket,释放资源。");
distorySocket(socketInfo.getSocketId());
return;
}

logger.debug("nameserver:distorySocket", DMLogger.RESULT_OK, "可关闭临时链接,关闭socket");
try {
if(socketInfo.getSocket() != null){
socketInfo.getSocket().close();
}
} catch (IOException e) {
logger.error("nameserver:distorySocket", DMLogger.RESULT_FAIL, "关闭名字服务器socket链接失败", e);
}
socketInfo = null;

}

/**
* @DateTime 2014-8-25 下午3:19:51
* @User liuxingmi
* @Desc 创建socket
* @return
* Socket
*/
public static Socket createSocket(){

String nameServerip1 = CloudpConfigUtil.DM_CONFIG.getNameSerIP1();
int namServerport1 = CloudpConfigUtil.DM_CONFIG.getNameSerPort1();
String nameServerip2 =  CloudpConfigUtil.DM_CONFIG.getNameSerIP2();
int namServerport2 = CloudpConfigUtil.DM_CONFIG.getNameSerPort2();
Socket socket = null;

try {// 尝试通过ip1第一次建立连接
socket = new Socket(nameServerip1, namServerport1);
logger.info("nameserver:login", DMLogger.RESULT_OK, "nameServerip1:" + nameServerip1 + ", namServerport1:" + namServerport1);
} catch (IOException e) {
logger.error("nameserver:login", DMLogger.RESULT_FAIL, "first link fail nameServerip1:" + nameServerip1 + ", namServerport1:" + namServerport1, e);
try {
// 如果第一次通过ip1建立连接失败,则进行第二次连接
socket = new Socket(nameServerip2, namServerport2);
logger.info("nameserver:login", DMLogger.RESULT_OK, "nameServerip2:" + nameServerip2 + ", namServerport2:" + namServerport2);
} catch (IOException e1) {
logger.error("nameserver:login", DMLogger.RESULT_FAIL, "second link fail nameServerip2:" + nameServerip2 + ", namServerport2:" + namServerport2, e);
return null;
}
}
return socket;
}

class CheckSocketThread extends Thread{
@Override
public void run() {
while (true) {
logger.debug("nameserver:checkSocket", DMLogger.RESULT_OK, "开始检测分布式链接状态。");
if(socketMap.size() < Integer.parseInt(ConfigConst.SOCKET_DEFAULT_COUNT)){
logger.info("nameserver:checkSocket", DMLogger.RESULT_OK, "分布式名字服务器socket链接小于默认链接数,增加socket链接。");
initSocket(false);
}

for (Map.Entry<Integer, SocketInfo> entry : socketMap.entrySet() ) {
SocketInfo socketInfo = entry.getValue();
if(socketInfo.getSocket() == null || socketInfo.isClosed()){
logger.error("nameserver:checkSocket", DMLogger.RESULT_FAIL, "第"+ entry.getKey()+"个socket链接已关闭,重新连接分布式。",null);
socketInfo.setSocket(createSocket());
} else {
if(socketInfo.isFree()){
boolean flag = NameServerUtils.getInstance().checkHeartbeat(socketInfo);
if( ! flag ){
logger.error("nameserver:checkSocket", DMLogger.RESULT_FAIL, "第"+ entry.getKey()+"个socket链接失败,重新连接分布式。",null);
socketInfo.setSocket(createSocket());
continue;
}
}
logger.debug("nameserver:checkSocket", DMLogger.RESULT_OK, "第"+ entry.getKey()+"个socket链接正常。");
}
}

try {
sleep(Long.valueOf(ConfigConst.SOCKET_CHECK_TIME));
} catch (Exception e) {
}
}
}
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: