Робота з SignalR з Android

Отже, після довгих мук, нарешті, мені вдалося розібратися зі всім функціоналом (що мені було потрібно для моєї роботи), що є в бібліотеці Signal R для Android.

Найголовніше, це jar файли, які потрібні нашій програмі для підключення і роботи з сервером.
Їх можна скачати з мого сайту, хоча ви теж самі можете зробити з Github:
http://smartarmenia.com/android_libs/signalr-client-sdk.jar
http://smartarmenia.com/android_libs/signalr-client-sdk-android.jar

Ще нам потрібна бібліотека gson, яку можна додати з maven dependencies в Android Studio або завантажити з google для Eclipse.

Так, після додавання цих бібліотек в папку libs нашого проекту, можна вже підключитися до сервера.

Я на своєму прикладі буду все робити з сервісу і AsyncTask-ами, як і звідки робити — ви будете вирішувати самі.

Перше, що потрібно робити — це викликати статичний метод до того, як почнемо використовувати signalr в Android.

Platform.loadPlatformComponent(new AndroidPlatformComponent());


Потім створюємо connection і hub(s):

HubConnection connection = new HubConnection("signalr_host");
HubProxy mainHubProxy = connection.createHubProxy("MainHub");


Після цього нам треба відловити state_change події, щоб контролювати нашим з'єднанням.

connection.stateChanged(new StateChangedCallback() {
@Override
public void stateChanged(ConnectionState connectionState, ConnectionState connectionState2) {
Log.i("SignalR", connectionState.name() + "->" + connectionState2.name());
}
});

це для зміни state (Disconnected, Connecting, Connected, Reconnecting)

Тепер отловим подія від'єднання:

connection.closed(new Runnable() {
@Override
public void run() {
Log.i("SignalR", "Closed");
connectSignalr();
}
});


Функція, яка викликає AsyncTask з'єднання (цю функцію потрібно викликати на початку сервісу і при Disconnect (Close)):

private void connectSignalr() {
try {
SignalRConnectTask signalRConnectTask = new SignalRConnectTask();
signalRConnectTask.execute(connection);
} catch (Exception ex) {
ex.printStackTrace();
}
}


Код класу SignalRConnectTask:

public class SignalRConnectTask extends AsyncTask {
@Override
protected Object doInBackground(Object[] objects) {
HubConnection connection = (HubConnection) objects[0];
try {
Thread.sleep(2000);
connection.start().get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
return null;
}
}


У нас вже є робоче підключення до сервера. Надалі нам знадобиться підписатися до подій або викликати функції hub-а.

subscribe

mainHubProxy.subscribe("newClient").addReceivedHandler(new Action<JsonElement[]>() {
@Override
public void run(JsonElement[] jsonElements) throws Exception {
Log.i("SignalR", "Message From Server: " + jsonElements[0].getAsString());
}
});


У масиві jsonElements — дані, які нам відправив сервер, вони можуть бути будь-якого serializable типу. В основному ми знаємо, якого вони типу і можемо перетворити на потрібний тип. Приклади робіть самі, але якщо виникнуть запитання або потрібні будуть приклади, напишіть в коментарях.

invoke

Це — для виклику методу hub-а. У нас є 2 варіанти, виклик методу, який повертає результат і нічого не повертає (Void).

Спочатку подивимося Void:

public class SignalRTestActionTask extends AsyncTask {
@Override
protected Object doInBackground(Object[] objects) {
if (connection.getState() == ConnectionState.Connected) {
Object param1 = objects[0];
Object param2 = objects[1];
try {
mainHubProxy.invoke("TestMethod", param1, param2).get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
return null;
}

@Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
}
}

new SignalRTestActionTask().execute(new Object(), new Object());


Знову ж таки, створюємо AsyncTask для виконання завдання.

Тепер теж саме зробимо і для іншого варіанту invoke, який повертає результат.

public class SignalRTestActionWithResultTask extends AsyncTask {
@Override
protected Object doInBackground(Object[] objects) {
if (connection.getState() == ConnectionState.Connected) {
Object result = null;
Object param1 = objects[0];
Object param2 = objects[1];
try {
result = mainHubProxy.invoke(Object.class, "TestMethod", param1, param2).get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
return result;
}

@Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
// Тут йде обробка результату.
}
}

new SignalRTestActionWithResultTask().execute(new Object(), new Object());


Все просто.

Далі настав час десеріалізації json-а класи.

Наприклад, наш метод в signalr повертає String — і ми це знаємо.
Для цього ми просто передаємо функцію invoke тип результату методу та отриманий результат за допомогою gson перетворює дані в потрібний тип.

String result = mainHubProxy.invoke(String.class, "TestMethod", param1, param2).get();


Коли приходить json array, то тип передаємо array, так:

String[] result = mainHubProxy.invoke(String[].class, "TestMethod", param1, param2).get();


Ну а наш array легко можна перетворити в Список:

List < String> strings = Arrays.asList(result);


Як тип результату, що повертається можна задати будь сериализуемый тип, наприклад, самі можемо створити власний клас зі структурою json об'єкта. Але це дива бібліотеки gson, якому ця стаття не присвячена.

Ось і все, мабуть. Якщо будуть питання та/або зауваження, напишіть, розберемося разом.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.