心跳机制
——>心跳机制:
->为什么要做心跳管理与上报(作用是什么?):
->长连接:通信上方建立TCP连接后进行通信,通信完毕后,不主动断开连接,而是保持连接;
特点:一直保持连接;
优点:通信速度块(在当前连接可用情况下,每次请求(响应)=简单的数据发送(接收))
免去了DNS解析、连接建立等时间
应用场景:双方通信需求频繁;具备实时需求
->长连接断开原因:
1.长连接所在进程被杀死;
2.NAT超时;
3.网络状态发生变化;
4.其他不可抗因素(网络状态差、DHCP的租期等等)
->高效维持长连接的解决方案:
1.长连接所在进程被杀死——> 进程保活
2.NAT超时——> 隔段时间完成与服务器的1次通信,从而避免网络链路中断,即心跳保活机制
3.网络状态发生变化——> 检测网络状态变化,从而断线重连,即断线重连机制
4.其他不可抗因素(网络状态差、DHCP的租期等等)——> 检测连接的存货&有效性,从而断线重连,即断线重连机制
->心跳保活机制简介:
->定义:一种每隔一段时间向对方发送自定义信息,以确保连接存活&有效的通信机制——>主要场景:客户端向服务器发送
->作用:...
->(原理)机制过程:
1.客户端每隔1段时间向服务器啊发送1个自定义的信息包;
2.服务器返回客户端1个自定义的信息包(也称:心跳应答)
3.最终形成客户端&服务器的一次完整的握手(完成通信=防止NAT超时;服务器应答=证明连接有效)
—>如何理解应用层的心跳?
客户端会开启一个定时任务,定时对已经建立连接的对端应用发送请求(这里的请求是特殊的心跳请求)
服务端则需要特殊处理该请求,返回响应。
(若心跳连续多次没有收到响应,客户端会认为连接不可用,主动断开连接)
->应用层心跳的设计细节:
以Dubbo为例,支持应用层的心跳,客户端和服务端都会开启一个HeartBeatTask,客户端在HeaderExchangerClient中开启,服务端将在HeaderExchangeServer开启。
->心跳上报管理技术选型:
->Retrofit:(由square公司开发,square在github上发布了很多优秀项目:otto(事件总线)、leakcanary(排查内存泄漏)、android-times-square(日历控件)、dagger(依赖注入)、picasso(异步加载图片)、okhttp(网络请求)、retrofit(网络请求))
->使用方法:(retrofit2.0依赖于okhttp,这里也不需要显示的导入okhttp(在retrofit中已经导入okhttp3了))
添加Gradle依赖项: compile 'com.squareup.retrofit2:retrofit:2.0.1'
创建API接口:在retrofit中通过一个Java接口作为http请求的api接口。
Retrofit在心跳机制中的应用
retrofit介绍:
一款面向安卓和Java的类型安全的HTTP 客户端;
Retrofit将你的HTTP API转换为Java接口:
public interface GitHubService {
@GET("users/{user}/repos")
Call<List<Repo>> listRepos(@Path("user") String user);
}
Retrofit类生成一个GitHubService接口的实现:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build();
GitHubService service = retrofit.create(GitHubService.class);
每个从GitHubService创建的Call可以向远程服务器发送一个同步或异步的HTTP请求:
Call<List<Repo>> repos = service.listRepos("octocat");
使用注解来描述HTTP请求:
URL参数替换并支持参数查询;
对象转换为请求体;
富文本请求和上传。
为什么要使用retrofit:
Retrofit作为简化HTTP请求的库,已经运行多年;
Retrofit可以利用接口,方法和注解参数(parameter annotations)来声明式定义一个请求应该如何被创建;
比较AsyncTask、Volley、Retrofit三者的请求时间 ==》 Retrofit2.0完胜
如何使用retrofit:
添加依赖项:compile 'com.squareup.retrofit2:retrofit:2.4.0'
private <T> T createClient(String url, Class<T> restService, OkHttpClient okHttpClient) {
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(
new Slf4jRetrofitLogger(restService));
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.valueOf(retrofitLogLevel));
OkHttpClient.Builder okHttpClientBuilder = okHttpClient.newBuilder().addInterceptor(retryInterceptor).addInterceptor(httpLoggingInterceptor);
Retrofit.Builder builder = new Retrofit.Builder()
.addConverterFactory(JacksonConverterFactory.create(objectMapper));
return builder
.client(okHttpClientBuilder.build())
.baseUrl(url)
.build()
.create(restService);
}
->HttpLoggingInterceptor用于拦截网络请求和响应,并输出Log。
->addConverterFactory添加Jackson转换器
->addCallAdapterFactory添加Rxjava2适配器
请求方法:
@GET("user/list")
也可以在URL中指定查询参数:
@GET("users/list?sort=desc")
操纵URL:(请求URL可以使用替换块来动态的更新,动态块是一个被{和}括起来的字母数字的字串,一个相关联的参数必须用@Path注解来使用相同的字串。)
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId);
查询参数也可以增加:
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @QueryMap Map<String, String> options);
可以用 Map 来组合成复杂的查询参数:
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int gruopId, @QueryMap Map<String, String> options);
请求体:(通过 @Body 注解,一个对象可以被指定为一个HTTP 请求体)
@POST("users/new")
Call<User> createUser(@Body User user);
格式化编码和多样性:(方法可以被声明发送格式化编码和多样性数据)
使用@FormUrlEncoded注解修饰的方法可以通过@Field注解来标识键值对:
@FormUrlEncoded
@POST("user/edit")
Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);
使用@Multipart注解修饰的方法可以通过@Part注解来声明各个部分:
@Multipart
@PUT("user/photo")
Call<User> updateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description);
......
retrofit配置:(retrofit可以将你的API接口转换成callable对象)
转换器:(默认的,retrofit只可以反序列化HTTP bodies成OkHttp的 ResponseBody 类型, 并且也只能通过@Body注解接收OkHttp的 RequestBody 类型)
Converters can be added to support other types. such as:
Gson: com.squareup.retrofit2:converter-gson
Jackson: com.squareup.retrofit2:converter-jackson
Moshi: com.squareup.retrofit2:converter-moshi
Protobuf: com.squareup.retrofit2:converter-protobuf
Wire: com.squareup.retrofit2:converter-wire
Simple XML: com.squareup.retrofit2:converter-simplexml
Scalars (primitives, boxed, and String): com.squareup.retrofit2:converter-scalars