⬆️ ⬇️

Work with SignalR from Android

So, after much torment, finally, I managed to figure out all the functionality (which I needed for my work), which is in the Signal R library for Android.



The most important thing is jar files that our program needs to connect and work with the server.

You can download them from my site, although you can also make them out of Github :

http://smartarmenia.com/android_libs/signalr-client-sdk.jar

http://smartarmenia.com/android_libs/signalr-client-sdk-android.jar



We also need the gson library, which can be added from maven dependencies in Android Studio or downloaded from google for Eclipse.



So, after adding these libraries to the libs folder of our project, you can already connect to the server.

')

I will do everything from the service and AsyncTask by my example, how and where to do - you will decide for yourself.



The first thing to do is call a static method before we start using signalr in Android.



Platform.loadPlatformComponent(new AndroidPlatformComponent()); 




Then we create a connection and hub (s):



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




After that we need to catch state_change events to control our connection.



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


this is for changing state (Disconnected, Connecting, Connected, Reconnecting)



Now we catch the disconnect event:



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




The function that calls the AsyncTask connection (this function must be called at the beginning of the service and when Disconnect (Close)):



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




Code class 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; } } 




We already have a working connection to the server. In the future, we will need to subscribe to events or call hub functions.



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()); } }); 




In the jsonElements array, the data that the server sent us, they can be of any serializable type. Basically we know what type they are and can convert to the desired type. Do it yourself, but if you have questions or need examples, write in the comments.



invoke



This is to call the hub method. We have 2 options, a method call that returns a result and returns nothing (Void).



First, look at 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()); 




Again, create an AsyncTask to complete the task.



Now we will do the same for another variant invoke, which returns the result.



 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()); 




It's simple.



Then it was time to deserialize json into classes.



For example, our method in signalr returns a String - and we know that.

To do this, we simply pass the function invoke to the type of the result of the method and the result obtained using gson converts the data to the desired type.



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




When the json array arrives, the type is passed to the array, so:



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




Well, our array can easily be converted to a List:



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




As a return type, you can specify any type that can be serialized, for example, we can create our own class with the object's json structure. But these are the wonders of the gson library, to which this article is not dedicated.



That's all, I guess. If you have questions and / or comments, write, we will understand together.

Source: https://habr.com/ru/post/301752/



All Articles