Сервер отправил события - как обрабатывать в Android - PullRequest
0 голосов
/ 27 июня 2019

Я создал приложение (в соответствии с текущей архитектурой Android MVVM с использованием LiveData и Retrofit). Приложение служит в качестве пульта дистанционного управления для системы освещения и доступа.

Я создал класс Repository, который реализует сетевой бэкэнд с использованием Retrofit, который выполняет вызовы моего REST API. Когда я вручную запрашиваю (используя GET) обновление статуса, я могу получить статус своего ввода-вывода. Однако мне нужно использовать отправленные сервером события для тех же данных в другом URI для обновлений состояния ввода-вывода.

Кажется, Retrofit не поддерживает эту функцию. Я обнаружил другие API, которые, кажется, обрабатывают SSE, такие как EventSource, EventSource-Android, OkHttp-EventSource и Oksse. Это все разные реализации EventSource? Чем они функционально отличаются друг от друга?

Я учусь на чтении кода, написанного другими людьми; где я могу найти функциональные примеры того, как они реализованы? Результаты моего поиска не дают никаких полезных примеров. Есть ли рекомендуемые рекомендации по обработке событий, отправленных сервером?

Я действительно не хочу опрашивать мой сервер на предмет обновлений, и меня смущает, почему на Android мало поддержки SSE.

Для справки, вот некоторые из классов, которые я реализовал до сих пор.

Модель данных:

import org.simpleframework.xml.Element;
import org.simpleframework.xml.Root;

@Root(name = "onboardGpio", strict = false)
public class OnboardGPIO
{
    @Element(name = "garageDoorFeedbackState")
    private String garageDoorState;

    @Element(name = "zoneOneState")
    private String zoneOneState;

    @Element(name = "zoneTwoState")
    private String zoneTwoState;

    @Element(name = "zoneThreeState")
    private String zoneThreeState;

    @Element(name = "systemArmedState")
    private String systemArmed;

    @Element(name = "panelTemperature")
    private String panelTemperature;

    @Element(name = "garageDoorRelayState")
    private String garageDoorRelayState;

    @Element(name = "zoneOneRelayState")
    private String zoneOneRelayState;

    @Element(name = "zoneTwoRelayState")
    private String zoneTwoRelayState;

    @Element(name = "zoneThreeRelayState")
    private String zoneThreeRelayState;

    ...getters & setters...
}

Класс репозитория

import androidx.lifecycle.MutableLiveData;
import ca.thirdgear.homeautomation.http.HomeAutomationAPI;
import ca.thirdgear.homeautomation.http.HomeAutomationController;
import ca.thirdgear.homeautomation.model.OnboardGPIO;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class DataRepository
{
    private static DataRepository dataRepository;
    private HomeAutomationController homeAutomationController;
    private HomeAutomationAPI homeAutomationAPIService;
    private MutableLiveData<String> zoneOneState;
    private MutableLiveData<String> zoneTwoState;
    private MutableLiveData<String> garageDoorState;

    public static DataRepository getInstance()
    {
        if(dataRepository == null)
        {
            dataRepository = new DataRepository();
        }
        return dataRepository;
    }

    private DataRepository()
    {
        homeAutomationController = HomeAutomationController.getInstance();
        homeAutomationAPIService = homeAutomationController.createService(HomeAutomationAPI.class);
        zoneOneState = new MutableLiveData<>();
        zoneTwoState = new MutableLiveData<>();
        garageDoorState = new MutableLiveData<>();
    }

    //get status of remote API I/O
    public void getIoStatus()
    {
        Call<OnboardGPIO> call = homeAutomationAPIService.getIoStatus();
        call.enqueue(new Callback<OnboardGPIO>() {
            @Override
            public void onResponse(Call<OnboardGPIO> call, Response<OnboardGPIO> response)
            {
                if(response.isSuccessful())
                {
                    zoneOneState.setValue(response.body().getZoneOneState());
                    zoneTwoState.setValue(response.body().getZoneTwoState());
              garageDoorState.setValue(response.body().getGarageDoorState());
                }
            }

            @Override
            public void onFailure(Call<OnboardGPIO> call, Throwable t)
            {
                //TODO
            }
        });

        ... other network calls ...
}

Сетевой класс

import okhttp3.Credentials;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import retrofit2.Retrofit;
import retrofit2.converter.simplexml.SimpleXmlConverterFactory;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

@SuppressWarnings("deprecation")
public class HomeAutomationController
{
    private static final String BASE_URL = "https://MY_URL/";
    private static HomeAutomationController homeAutomationController;
    private OkHttpClient okHttpClient;
    private Retrofit retrofit;

    public static HomeAutomationController getInstance()
    {
        if(homeAutomationController == null)
        {
            homeAutomationController = new HomeAutomationController();
        }
        return homeAutomationController;
    }

    private HomeAutomationController()
    {
        //create OkHttpClient
        okHttpClient = new OkHttpClient().newBuilder().addInterceptor(new Interceptor() {
            @Override
            public okhttp3.Response intercept(Chain chain) throws IOException {
            Request originalRequest = chain.request();

            Request.Builder builder = originalRequest.newBuilder().header("Authorization",
                    Credentials.basic("USERNAME", "PASSWORD"));

            Request newRequest = builder.build();
            return chain.proceed(newRequest);
            }
        })
            .readTimeout(0, TimeUnit.SECONDS)
            .build();

        //create retrofit object
        retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(SimpleXmlConverterFactory.create())
                .client(okHttpClient)
                .build();
    }

    //create and return http service
    public <S> S createService(Class <S> serviceClass)
    {
        return retrofit.create(serviceClass);
    }

}
...