Work with SignalR from Android
- From the sandbox
- Tutorial
The most important thing is the jar files that our program needs to connect and work with the server.
They can be downloaded from my site, although you yourself can also make them from 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.
By my example, I will do everything from the service and AsyncTask, how and where to do it - you will decide for yourself.
The first thing to do is call the static method before we start using signalr in Android.
Platform.loadPlatformComponent(new AndroidPlatformComponent());
Then create connection and hub (s):
HubConnection connection = new HubConnection("signalr_host");
HubProxy mainHubProxy = connection.createHubProxy("MainHub");
After that, we need to catch state_change events in order 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 with Disconnect (Close)):
private void connectSignalr() {
try {
SignalRConnectTask signalRConnectTask = new SignalRConnectTask();
signalRConnectTask.execute(connection);
} catch (Exception ex) {
ex.printStackTrace();
}
}
SignalRConnectTask class code:
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 the hub functions.
subscribe
mainHubProxy.subscribe("newClient").addReceivedHandler(new Action() {
@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 to us, it 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 for invoking a hub method. We have 2 options, a method call that returns the result and returns nothing (Void).
First, let's see 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 the other invoke variant, 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());
Everything is simple.
Next, it’s time to deserialize json into classes.
For example, our method in signalr returns String - and we know that.
To do this, we simply pass the invoke function the type of the method result and the result 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 array, like this:
String[] result = mainHubProxy.invoke(String[].class, "TestMethod", param1, param2).get();
Well, our array can easily be converted to List:
List strings = Arrays.asList(result);
As a return type, you can specify any serializable type, for example, we ourselves can create our own class with the json structure of the object. But these are the wonders of the gson library, which this article is not about.
That's all, I guess. If you have questions and / or comments, write, we will understand together.