Итак, после долгих мучений, наконец, мне удалось разобраться со всем функционалом (что мне нужно было для моей работы), что есть в библиотеке 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.
Потом создаем connection и hub(s):
После этого нам надо отловить state_change события, чтобы контролировать нашим соединением.
это для изменения state (Disconnected, Connecting, Connected, Reconnecting)
Теперь отловим событие отсоединения:
Функция, которая вызывает AsyncTask соединения (эту функцию нужно вызвать в начале сервиса и при Disconnect (Close)):
Код класса SignalRConnectTask:
У нас уже есть рабочее подключение к серверу. В дальнейшем нам понадобится подписаться к событиям или вызвать функции hub-а.
subscribe
В массиве jsonElements — данные, которые нам отправил сервер, они могут быть любого serializable типа. В основном мы знаем, какого они типа и можем преобразовать на нужный тип. Примеры делайте сами, но если будут вопросы или нужны будут примеры, напишите в комментариях.
invoke
Это — для вызова метода hub-а. У нас есть 2 варианта, вызов метода, который возвращает результат и ничего не возвращает (Void).
Сначала посмотрим Void:
Опять же, создаем AsyncTask для выполнения задачи.
Теперь тоже самое сделаем и для другого варианта invoke, который возвращает результат.
Все просто.
Далее настало время десериализации json-а в классы.
Например, наш метод в signalr возвращает String — и мы это знаем.
Для этого мы просто передаем функцию invoke тип результата метода и полученный результат с помощью gson преобразует данные в нужный тип.
Когда приходит json array, то тип передаем array, так:
Ну а наш array легко можно преобразовать в List:
Как тип возвращаемого результата можно задать любой сериализуемый тип, например, сами можем создать собственный класс со структурой json объекта. Но это чудеса библиотеки gson, которому эта статья не посвящена.
Вот и все, наверное. Если будут вопросы и/или замечания, напишите, разберемся вместе.
Самое главное, это 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:
List<String> strings = Arrays.asList(result);
Как тип возвращаемого результата можно задать любой сериализуемый тип, например, сами можем создать собственный класс со структурой json объекта. Но это чудеса библиотеки gson, которому эта статья не посвящена.
Вот и все, наверное. Если будут вопросы и/или замечания, напишите, разберемся вместе.