`
桥下一粒砂
  • 浏览: 209622 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

【开源框架】一个基于回调机制的多线程异步Http连接框架

阅读更多

Async Http Connection

源码地址: https://github.com/chenyoca/async-http-connection

 

  • a multithread callback-based async http connection library. it can be use on android project or general java project.
  • 一个基于回调机制的多线程异步Http连接库。它可用于Android项目或者一般Java项目。

适用

Async HTTP Connection为简单的Http连接请求而设计。适用于API SDK等小数据传输项目,设计目标为Android项目。
当前项目属性为Java项目,并使用JUnit4作为测试环境,主要是Android项目调试不方便。
如果需要完善的功能,推荐一位国外大神的项目:[android-async-http](https://github.com/loopj/android-async-http)

特点

  • 简单 提供POST和GET两个接口,通过扩展接口可设置PUT、DELETE方法。通过参数和回调接口完成整个Http连接的交互。
  • 轻量 纯JDK实现,不依赖第三方Jar包。
  • 快速 采用Executor多线程并发框架,秉承它的并发处理优势。
  • 可扩展 框架提供Invoker扩展,通过实现RequestInvoker可方便的把HttpClient等优秀框架整合到项目中。

测试辅助

在多线程测试中,如果并发多条线程,则测试主线程需要等待所在测试子线程全部返回后才结束。一般采用两种方式:1、Thread.sleep()方式。2、CountDown计数方式。

所有问题的的解决方式都不只有一种,看谁的方式更好更——优雅而已。

比如:本框架内置多线程测试辅助工具组合 ResponseCallbackTrace + ThreadWaiter。可以利用简单的几个方法,就解决并发线程等待的问题。

多线程测试辅助的使用方法

使用方法很简单

  1. 创建回调接口动态代理
    protected final ResponseCallbackTrace callbackTrace = new ResponseCallbackTrace();

ResponseCallbackTrace 是一个动态代理实现类,它可以监听 ResponseCallback 的调用。并将线程执行情况记录在ThreadWaiter中。

  1. 对回调接口添加代理
    for(String url : urls){
            http.get(url, null,
                    // 使用回调动态代理,可以自动处理等待其它线程返回的问题
                    callbackTrace.trace(callback));
        }

  1. 等待所有线程返回
    //等待所有线程返回
    ThreadWaiter.waitingThreads();

完整的测试代码

    public class UrlsTestCase{

    final static String[] AvailableUrls = {
        "http://www.lurencun.com",
        "http://www.163.com",
        "http://www.126.com",
        "http://www.google.com.hk",
        "http://www.qq.com",
        "http://www.ifeng.com",
        "http://www.renren.com",
        "http://www.58.com",
        "http://www.psbc.com",
        "http://www.suning.com",
        "http://www.jumei.com",
        "http://www.xiu.com",
        "http://www.letv.com",
        "http://www.miercn.com",
        "http://www.jrj.com",
        "http://www.suning.com",
        "http://www.9ku.com",
        "http://www.jumei.com",
        "http://www.ctrip.com",
        "http://www.tuniu.com",
        "http://www.icbc.com",
        "http://www.ccb.com",
        "http://www.gexing.com",
        "http://www.nipic.com",
        "http://www.jxedt.com",
        "http://www.iqiyi.com",
        "http://www.skycn.com",
        "http://www.7k7k.com",
    };

    protected ResponseCallback callback = new ResponseCallback() {

        @Override
        public void onResponse(InputStream response,URL url) {
            System.out.println("[test GET] --> response back, url = "+url);
            Assert.assertNotNull(response);
        }

        @Override
        public void onError(Throwable exp) {
            Assert.fail(exp.getMessage());
            System.err.println("[test GET] --> response error");
        }

        @Override
        public void onSubmit(URL url,ParamsWrapper params) {}

        @Override
        public void onResponseWithToken(InputStream response, URL url, Object token) {}
    };

    final AsyncHttpConnection http = AsyncHttpConnection.getInstance();

    final ResponseCallbackTrace callbackTrace = new ResponseCallbackTrace();

    @Test
    public final void test(){

        testAllUrls(AvailableUrls);

        //等待所有线程返回
        ThreadWaiter.waitingThreads();
    }

    protected void testAllUrls(String[] urls){

        for(String url : urls){
            http.get(url, null,
                    // 使用回调动态代理,可以自动处理等待其它线程返回的问题
                    callbackTrace.trace(callback));
        }
    }

}


使用

默认使用SimpleHttpInvoker类执行Http连接,基于HttpUrlConnection实现。 提供两个接口实现类:BinaryResponseHandler、StringResponseHandler。分别处理二进制数据和字符数据。

更多例子见源目录的 test 目录

简单的例子

//使用Get方法,取得服务端响应流:
AsyncHttpConnection http = AsyncHttpConnection.getInstance();
ParamsWrapper params = ...;
String url = ...

// callback with InputStream

    int requestId = http.get(url, params, new ResponseCallback() {

        @Override
        public void onResponse(InputStream response,URL url) {
            System.out.println("[test GET] --> response back, url = "+url);
            Assert.assertNotNull(response);
        }

        @Override
        public void onError(Throwable exp) {
            System.err.println("[test GET] --> response error, url = "+url);
        }

        @Override
        public void onSubmit(URL url,ParamsWrapper params) {
        }
    });

// callback with String 

    int requestId2 = http.get(url, null, new StringResponseHandler() {

        @Override
        public void onSubmit(URL url,ParamsWrapper params) {
        }

        @Override
        public void onError(Throwable exp) {
            exp.printStackTrace();
            requestBack();
        }

        @Override
        public void onResponse(String content, URL url) {
            System.out.println("content->"+content);
            requestBack();
        }
    });

// callback with Binary 

    http.get(url, null, new BinaryResponseHandler() {

        @Override
        public void onSubmit(URL url, ParamsWrapper params) {
        }

        @Override
        public void onError(Throwable exp) {
            exp.printStackTrace();
            requestBack();
        }

        @Override
        public void onResponse(byte[] data, URL url) {
            final int size = 4465;
            Assert.assertEquals(size, data.length);
            System.out.println("Data size -> "+String.valueOf(data.length));
            requestBack();
        }
    });

//使用POST方法,取得服务端响应流:
AsyncHttpConnection http = AsyncHttpConnection.getInstance();
ParamsWrapper params = ...;
String url = ...

// callback with Stream

    int requestId = http.post(url, params, new ResponseCallback() {

        @Override
        public void onResponse(InputStream response,URL url) {
            System.out.println("[test POST] --> response back, url = "+url);
            Assert.assertNotNull(response);
            requestBack();
        }

        @Override
        public void onError(Throwable exp) {
            System.err.println("[test POST] --> response error, url = "+url);
            requestBack();
        }

        @Override
        public void onSubmit(URL url) {
        }
    });

// callback with String

    http.post(url, params, new StringResponseHandler() {
        @Override
        public void onSubmit(URL url,ParamsWrapper params) { 
            System.out.println(">> target: "+url.getHost()+" --> "+url.getPath());
        }
        @Override
        public void onError(Throwable exp) {
            exp.printStackTrace();
        }
        @Override
        public void onResponse(String content, URL url) {
            System.out.println("Return -> \n"+content);
        }

    });

更详细的例子

//使用POST方法,取得服务端响应流:
AsyncHttpConnection http = AsyncHttpConnection.getInstance();
final int KEY_VAL = 24;
ParamsWrapper params = new ParamsWrapper();
params.put("firstname", "chen");
params.put("lastname", "yoca");
params.put("foo", KEY_VAL);
params.put("cookiename", KEY_VAL);
params.put("cookievalue", KEY_VAL);
int requestId = http.post(url, params, new StringResponseHandler() {

    @Override
    public void onSubmit(URL url) { 
        System.out.println(">> target: "+url.getHost()+" --> "+url.getPath());
    }

    @Override
    public void onError(Throwable exp) {
        requestBack();
        exp.printStackTrace();
    }

    @Override
    public void onResponse(String content, URL url) {
        Assert.assertNotNull(content);
        boolean containsKey = content.contains(String.valueOf(KEY_VAL));
        Assert.assertEquals(true, containsKey);
        requestBack();
    }
});

// 在大量并发的异步请求情况下,每个请求的回调可能需要一个标识码来标记这个回调结果。
// 有两种方式来解决这个问题:
// 1、使用get和post返回的RequestID来标识,但这需要对RequestID进行管理
// 2、使用get和post的token参数

AsyncHttpConnection http = AsyncHttpConnection.getInstance();
final int KEY_VAL = 24;
ParamsWrapper params = new ParamsWrapper();
params.put("firstname", "chen");
params.put("lastname", "yoca");
params.put("foo", KEY_VAL);
params.put("cookiename", KEY_VAL);
params.put("cookievalue", KEY_VAL);

//  ******** 利用token 接口 ************
Object token = "1234566";

// 如果调用了带token的方法,回调的方法将是onResponse(String content, URL url, Object token)
int requestId = http.post(url, params, token, new StringResponseHandler() {

    @Override
    public void onSubmit(URL url) { 
        System.out.println(">> target: "+url.getHost()+" --> "+url.getPath());
    }

    @Override
    public void onError(Throwable exp) {
        requestBack();
        exp.printStackTrace();
    }

    @Override
    public void onResponse(String content, URL url, Object token) {
        // token == "1234566" Token被传到这里作为标识
        Assert.assertNotNull(content);
        boolean containsKey = content.contains(String.valueOf(KEY_VAL));
        Assert.assertEquals(true, containsKey);
        requestBack();
    }
});

HTTP Method

需要使用其它Http Mehtod,可以通过

* sendRequest(String url,ParamsWrapper params,HttpMethod method,Object token,ResponseCallback callback)
* sendRequest(String url,ParamsWrapper params,HttpMethod method, ResponseCallback callback)

接口调用。

分享到:
评论

相关推荐

    异步和多线程socket通讯

    本文将深入探讨"异步和多线程socket通讯"这一主题,基于提供的描述和标签,我们将讨论如何利用多线程和异步机制来提升socket通信的效率和响应性。 首先,Socket是一种在应用程序与网络服务之间建立连接的接口,它...

    解决任意的多线程并行、串行、阻塞、依赖、回调的并行框架

    本文将深入探讨如何解决多线程中的并行、串行、阻塞、依赖和回调问题,以及京东主App后台采用的一站式解决方案——"解决任意的多线程并行、串行、阻塞、依赖、回调的并行框架"。 首先,我们要理解并行和串行的概念...

    android 异步操作框架

    Android提供了多种异步处理框架,其中一个被广泛使用的开源框架是“android-async-http”,它是一个轻量级、高性能的网络库,非常适合进行HTTP请求。 **Android异步操作的重要性** 在Android系统中,主线程负责处理...

    Android开源框架源码分析

    RxJava是一个基于响应式编程的库,它使用Observable和Subscriber模式来处理事件流,支持强大的异步操作。RxJava使用强大的链式调用和丰富的操作符来控制事件流的转换、合并、过滤等操作,使异步处理更为直观和灵活。...

    基于Android的多线程上传与下载源码

    多线程下载javaSe`可能包含了一个使用Java标准库实现的多线程下载示例。在Java中,可以使用`java.util.concurrent`包下的`ExecutorService`和`Future`接口来管理线程池和任务执行。通过创建多个线程,每个线程负责...

    Android设计思想解读开源框架.pdf

    - **RxJava**:一个基于观察者模式的响应式编程库。它支持链式调用,可以轻松地组合多个操作符来构建复杂的数据流处理流程。 **6.2 扩展的观察者模式** - **Subject**:作为Observable和Observer的桥梁,允许多个...

    QT多线程调用摄像头录屏

    为了确保线程间通信的安全,可能需要使用信号和槽机制或者异步回调函数来更新UI状态。 5. **用户界面交互**: 用户界面设计是整个应用的关键部分。用户需要能够轻松地开启和停止录像,选择摄像头,指定保存路径,...

    基于Java的轻量级同步异步统一处理框架,基于协程思想构建.zip

    总的来说,这个基于Java的轻量级同步异步统一处理框架为开发者提供了一种新的并发处理方式,通过协程思想简化了异步编程,提高了代码效率和可读性。对于希望优化并发性能或处理大量并发请求的Java项目来说,这是一个...

    大恒-双相机开发-C#-多线程-项目开源

    对于想要深入学习C#图像处理和多线程编程的开发者来说,这是一个非常有价值的开源项目。通过研究这个项目,我们可以了解到如何在实际应用中有效地结合各种技术,解决复杂的问题,提升系统的性能。

    swift-仿SDWebImage网络图片框架Block回调传值思路附Demo

    例如,我们可以定义一个图片加载接口,包含一个完成回调,该回调接收一个UIImage对象和一个错误信息,以便在图片加载成功或失败时进行处理。 4. **Demo实现**:DEEWebImage-master可能是这个项目的源代码示例,它...

    《Linux多线程服务端编程:使用muduo C++网络库》.(陈硕).[PDF]@ckook

    书中详细介绍了muduo库的使用方法,包括基本的网络连接管理、套接字操作、事件回调机制、时间轮定时器、缓冲区管理等。读者将学习到如何利用muduo库中的类和接口,来编写简洁、可维护的代码,实现并发服务端功能。 ...

    开源nio框架cindy源码

    Cindy是一款基于Java NIO(Non-blocking Input/Output)的开源框架,它的设计目标是提供高效、可扩展的网络通信能力。NIO是一种不同于传统I/O的编程模型,它允许程序在等待数据读写时执行其他任务,从而提高了并发...

    开源框架android-async-http-master

    `android-async-http`是一个非常流行的开源框架,用于简化Android应用程序中的HTTP网络请求。本文将深入探讨这个框架的核心特性、使用方法以及其在处理JSON数据方面的优势。 一、框架简介 `android-async-http`,...

    Android afinal开源框架实例源码.rar

    3. **异步操作**:考虑到Android的多线程需求,Afinal支持异步数据库操作,避免了主线程阻塞,提高了用户体验。使用AsyncFinalDb可以在后台线程中执行数据库操作,而结果则可以通过回调函数传递到主线程进行处理。 ...

    Android开源框架Android-async-http的研究与应用.pdf

    除了上述特点外,Android-async-http作为一个异步框架,采用了线程池来处理并发请求,这意味着该框架能够在多线程环境中有效地管理网络请求,从而提高应用性能。 在总结Android-async-http的优点时,我们可以归纳为...

    异步的 RPC

    - **回调函数**: 异步RPC通常涉及回调函数,客户端在发送请求时提供一个回调函数的引用,服务器在完成处理后通过这个回调函数将结果返回给客户端。 ### 2. 异步RPC的工作流程 1. **请求发起**: 客户端调用异步RPC...

    一个基于libevent开发的网络框架,跨平台.zip

    1. **事件驱动模型**:FastNet采用libevent的事件驱动模型,当有网络事件发生时,例如数据到达或连接请求,框架会自动触发相应的回调函数,开发者只需关注业务逻辑,而不用关心底层的网络操作。 2. **多路复用**:...

    Java Socket 开发框架【susu】

    Java Socket 开发框架【susu】是一个自定义的、基于异步模式的网络通信解决方案,专为Java开发者设计。在Java编程中,Socket是实现客户端与服务器之间通信的基础,它提供了进程间的网络通信能力。而将Socket编程封装...

    基于嵌入式LINUX的异步事件驱动数据采集模型.pdf

    ACE是一个跨平台的C++框架,能够有效地处理并发和分布式系统中的复杂通信问题。 在该模型中,数据采集任务被转化为一系列异步事件,每个事件都有自己的事件句柄。当数据源触发事件时,操作系统会自动进行事件分离和...

    牛逼的开源android框架

    11. **Kotlin Coroutines** - Kotlin语言的协程库,解决了Android平台上的多线程问题,提供了轻量级的并发机制,使异步编程更加简单。 12. **Lifecycle** - Android Jetpack的一部分,帮助管理组件(如Activity和...

Global site tag (gtag.js) - Google Analytics