海康安防平台SDK抓图补充

前段时间发了一篇利用海康SDK抓图的示例,里面提到,开发的时候既可以直接在pom里引用sdk,也可以将sdk源码放到自己的工程里以便修改。

上次发的文章里面,提到了修改sdk源码中的超时时间。这两天又发现了一个新问题,当我利用多线程远程抓图时,由于网络问题,每次抓图都要耗费几秒钟时间,导致后面的线程一直排队,直到异常扔出来。又翻了一下SDK源码,发现厂商给的东西属实有点简单到过分了,单例模式搞了一个简单的CloseableHttpClient对象,必然是要阻塞的。所以这里记录一下,我们修改HttpUtil工具类的源码,给CloseableHttpClient增加一个连接池。

要修改的位置位于HttpUtil类的wrapClient()方法。里面的GET、POST方法都是通过调用wrapClient来获得httpClient的实例的,所以改这一个地方就可以了。废话不多直接上源码了,创建线程池的部分也是在网上copy的,少部分进行了一些改动,大家根据自己实际情况去修改就可以了。

	public static CloseableHttpClient wrapClient(String host, int connectTimeout) throws NoSuchAlgorithmException, KeyManagementException {
        if (closeableHttpClient == null) {
            synchronized (LOCK) {
                if (closeableHttpClient == null) {
                    SSLConnectionSocketFactory socketFactory = null;
                    if (host.startsWith("https://")) {
                        socketFactory = sslClientNew();
                    }

                    HttpClientBuilder httpClientBuilder = HttpClients.custom();
                    httpClientBuilder.evictIdleConnections(1, TimeUnit.MINUTES)      // 定期回收空闲连接
                            .evictExpiredConnections()// 定期回收过期连接
                            .setSSLSocketFactory(socketFactory)
                            //.setDefaultRequestConfig(getConfig());
                            .setDefaultRequestConfig(RequestConfig
                                            .custom()
                                            .setAuthenticationEnabled(false)
                                            .setCircularRedirectsAllowed(false)
                                            .setSocketTimeout(connectTimeout)
                                            .setConnectTimeout(connectTimeout)
                                            .setConnectionRequestTimeout(1000)
                                            .setCookieSpec(CookieSpecs.IGNORE_COOKIES)
                                            .build()) // 设置默认请求配置
                            .setConnectionReuseStrategy(DefaultConnectionReuseStrategy.INSTANCE) // 连接重用策略 是否能keepAlive
                            .setKeepAliveStrategy(DefaultConnectionKeepAliveStrategy.INSTANCE)// 长连接配置,即获取长连接生产多长时间
                            .setRetryHandler(new DefaultHttpRequestRetryHandler(0, false));// 重试次数 默认3次 此处禁用

                    Registry socketFactoryRegistry =
                            RegistryBuilder.create()
                                    .register("https", socketFactory)
                                    .register("http", new PlainConnectionSocketFactory()).build();

                    final int conExpire = 15;// 长连接闲置过期时间,可配置
                    cm = new PoolingHttpClientConnectionManager(socketFactoryRegistry, null, null, null, conExpire,
                            TimeUnit.SECONDS);
                    cm.setDefaultConnectionConfig(ConnectionConfig.DEFAULT);
                    cm.setMaxTotal(MAX_CONNECTION_NUM);
                    cm.setDefaultMaxPerRoute(MAX_PER_ROUTE);
                    // 设置长连接心跳检测,设置超时,禁用nagle算法
                    cm.setDefaultSocketConfig(SocketConfig.custom().setSoKeepAlive(true).setSoTimeout(connectTimeout).setTcpNoDelay(true).build());
                    cm.setValidateAfterInactivity(-1);// 每次取重用的连接时禁止连接活性检测,可以提升性能

                    httpClientBuilder.setConnectionManager(cm);
                    httpClientBuilder.setConnectionManagerShared(false);

                    closeableHttpClient = httpClientBuilder.build();

                    // 过期检测
                    Thread staleCheckThread = new Thread(() -> {
                        while (true) {
                            try {
                                Thread.sleep(10000);
                                cm.closeExpiredConnections();
                                cm.closeIdleConnections(conExpire, TimeUnit.SECONDS);
                            } catch (Exception e) {
                                throw new RuntimeException(e);
                            }
                        }

                    }, "HttpInvoker-coonection-stale-check-thread");
                    // 设置成为守护线程
                    staleCheckThread.setDaemon(true);
                    staleCheckThread.start();

                    // 程序退出时,关闭httpClient
                    Runtime.getRuntime().addShutdownHook(new Thread(() -> {
                        try {
                            closeableHttpClient.close();
                        } catch (IOException e) {
                            throw new RuntimeException(e);
                        }
                    }, "srsynchronize-httpInvoker-shutdown-thread"));

                    return closeableHttpClient;
                }
            }
        }
        return closeableHttpClient;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值