溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

怎么在Java中按時(shí)間梯度異步回調(diào)接口

發(fā)布時(shí)間:2021-03-09 16:17:46 來源:億速云 閱讀:284 作者:Leah 欄目:編程語言

這篇文章給大家介紹怎么在Java中按時(shí)間梯度異步回調(diào)接口,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

  用到的技術(shù)如下:

?http請求庫,retrofit2
?隊(duì)列,LinkedBlockingQueue
?調(diào)度線程池,ScheduledExecutorService

怎么在Java中按時(shí)間梯度異步回調(diào)接口

3. 主要代碼說明

3.1 回調(diào)時(shí)間梯度的策略設(shè)計(jì)

采用枚舉來對策略規(guī)則進(jìn)行處理,便于代碼上的維護(hù),該枚舉設(shè)計(jì)三個(gè)參數(shù),級(jí)別、回調(diào)間隔、回調(diào)次數(shù);

/**
 * 回調(diào)策略
 */
public enum CallbackType {
  //等級(jí)1,10s執(zhí)行3次
  SECONDS_10(1, 10, 3),
  //等級(jí)2,30s執(zhí)行2次
  SECONDS_30(2, 30, 2),
  //等級(jí)3,60s執(zhí)行2次
  MINUTE_1(3, 60, 2),
  //等級(jí)4,5min執(zhí)行1次
  MINUTE_5(4, 300, 1),
  //等級(jí)5,30min執(zhí)行1次
  MINUTE_30(5, 30*60, 1),
  //等級(jí)6,1h執(zhí)行2次
  HOUR_1(6, 60*60, 1),
  //等級(jí)7,3h執(zhí)行2次
  HOUR_3(7, 60*60*3, 1),
  //等級(jí)8,6h執(zhí)行2次
  HOUR_6(8, 60*60*6, 1);

  //級(jí)別
  private int level;
  //回調(diào)間隔時(shí)間 秒
  private int intervalTime;
  //回調(diào)次數(shù)
  private int count;
}

3.2 數(shù)據(jù)傳輸對象設(shè)計(jì)

聲明抽象父類,便于其他對象調(diào)用傳輸繼承。

/**
 * 消息對象父類
 */
public abstract class MessageInfo {
  //開始時(shí)間
  private long startTime;
  //更新時(shí)間
  private long updateTime;
  //是否回調(diào)成功
  private boolean isSuccess=false;
  //回調(diào)次數(shù)
  private int count=0;
  //回調(diào)策略
  private CallbackType callbackType;
}

要傳輸?shù)膶ο?,繼承消息父類;

/**
 * 工單回調(diào)信息
 */
public class WorkOrderMessage extends MessageInfo {
  //車架號(hào)
  private String vin;
  //工單號(hào)
  private String workorderno;
  //工單狀態(tài)
  private Integer status;
  //工單原因
  private String reason;
  //操作用戶
  private Integer userid;
}

3.3 調(diào)度線程池的使用

//聲明線程池,大小為16
private ScheduledExecutorService pool = Executors.newScheduledThreadPool(16);

...略

while (true){
      //從隊(duì)列獲取數(shù)據(jù),交給定時(shí)器執(zhí)行
      try {
        WorkOrderMessage message = MessageQueue.getMessageFromNext();
        long excueTime = message.getUpdateTime()+message.getCallbackType().getIntervalTime()* 1000;
        long t = excueTime - System.currentTimeMillis();
        if (t/1000 < 5) {//5s之內(nèi)將要執(zhí)行的數(shù)據(jù)提交給調(diào)度線程池
          System.out.println("MessageHandleNext-滿足定時(shí)器執(zhí)行條件"+JSONObject.toJSONString(message));
          pool.schedule(new Callable<Boolean>() {
            @Override
            public Boolean call() throws Exception {
              remoteCallback(message);
              return true;
            }
          }, t, TimeUnit.MILLISECONDS);
        }else {
          MessageQueue.putMessageToNext(message);
        }
      } catch (InterruptedException e) {
        System.out.println(e);
      }
    }

3.4 retrofit2的使用,方便好用。

具體可查看官網(wǎng)相關(guān)文檔進(jìn)行了解,用起來還是比較方便的。http://square.github.io/retrofit/

retrofit初始化:

import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class RetrofitHelper {
  private static final String HTTP_URL = "http://baidu.com/";
  private static Retrofit retrofit;
  public static Retrofit instance(){
    if (retrofit == null){
      retrofit = new Retrofit.Builder()
          .baseUrl(HTTP_URL)
          .addConverterFactory(GsonConverterFactory.create())
          .build();
    }
    return retrofit;
  }
}

如果需要修改超時(shí)時(shí)間,連接時(shí)間等可以這樣初始話,Retrofit采用OkHttpClient

import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import java.util.concurrent.TimeUnit;
public class RetrofitHelper {
  private static final String HTTP_URL = "http://baidu.com/";
  private static Retrofit retrofit;
  public static Retrofit instance(){
    if (retrofit == null){
      retrofit = new Retrofit.Builder()
          .baseUrl(HTTP_URL)
          .client(new OkHttpClient.Builder()
              .connectTimeout(30, TimeUnit.SECONDS)//連接時(shí)間
              .readTimeout(30, TimeUnit.SECONDS)//讀時(shí)間
              .writeTimeout(30, TimeUnit.SECONDS)//寫時(shí)間
              .build())
          .addConverterFactory(GsonConverterFactory.create())
          .build();
    }
    return retrofit;
  }
}

Retrofit使用通過接口調(diào)用,要先聲明一個(gè)接口;

import com.alibaba.fastjson.JSONObject;
import com.woasis.callbackdemo.bean.WorkOrderMessage;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.POST;
public interface WorkOrderMessageInterface {
  @POST("/api")
  Call<JSONObject> updateBatteryInfo(@Body WorkOrderMessage message);
}

接口和實(shí)例對象準(zhǔn)備好了,接下來就是調(diào)用;

private void remoteCallback(WorkOrderMessage message){
    //實(shí)例接口對象
    WorkOrderMessageInterface workOrderMessageInterface = RetrofitHelper.instance().create(WorkOrderMessageInterface.class);
    //調(diào)用接口方法
    Call<JSONObject> objectCall = workOrderMessageInterface.updateBatteryInfo(message);
    System.out.println("遠(yuǎn)程調(diào)用執(zhí)行:"+new Date());
    //異步調(diào)用執(zhí)行
    objectCall.enqueue(new Callback<JSONObject>() {
      @Override
      public void onResponse(Call<JSONObject> call, Response<JSONObject> response) {
        System.out.println("MessageHandleNext****調(diào)用成功"+Thread.currentThread().getId());
        message.setSuccess(true);
        System.out.println("MessageHandleNext-回調(diào)成功"+JSONObject.toJSONString(message));
      }
      @Override
      public void onFailure(Call<JSONObject> call, Throwable throwable) {
        System.out.println("MessageHandleNext++++調(diào)用失敗"+Thread.currentThread().getId());
        //失敗后再將數(shù)據(jù)放入隊(duì)列
        try {
          //對回調(diào)策略初始化
          long currentTime = System.currentTimeMillis();
          message.setUpdateTime(currentTime);
          message.setSuccess(false);
          CallbackType callbackType = message.getCallbackType();
          //獲取等級(jí)
          int level = CallbackType.getLevel(callbackType);
          //獲取次數(shù)
          int count = CallbackType.getCount(callbackType);
          //如果等級(jí)已經(jīng)最高,則不再回調(diào)
          if (CallbackType.HOUR_6.getLevel() == callbackType.getLevel() && count == message.getCount()){
            System.out.println("MessageHandleNext-等級(jí)最高,不再回調(diào), 線下處理:"+JSONObject.toJSONString(message));
          }else {
            //看count是否最大,count次數(shù)最大則增加level
            if (message.getCount()<callbackType.getCount()){
              message.setCount(message.getCount()+1);
            }else {//如果不小,則增加level
              message.setCount(1);
              level += 1;
              message.setCallbackType(CallbackType.getTypeByLevel(level));
            }
            MessageQueue.putMessageToNext(message);
          }
        } catch (InterruptedException e) {
          e.printStackTrace();
          System.out.println("MessageHandleNext-放入隊(duì)列數(shù)據(jù)失敗");
        }
      }
    });
  }

3.5結(jié)果實(shí)現(xiàn)

怎么在Java中按時(shí)間梯度異步回調(diào)接口

關(guān)于怎么在Java中按時(shí)間梯度異步回調(diào)接口就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI