I already read these topics:
how to use SignalR in Android
Android Client doesn't get data but .net client getting data from SignalR server
I write a simple chat system with Android that works with SignalR.
It is supposed to the clients send messages (by calling SendMessage
method on the server) and the server should call the NewMessage
method on the clients.
Here is my ChatHub
class (simplified) written in C#.
public class ChatHub : Hub
{
// Store the clients connections Id
static readonly List<string> _connectedClients;
public override Task OnConnected()
{
// Keep connections id
// This section works fine and when the android device connects to the server,
// Its connection id will stored.
_connectedClients.Add(Context.ConnectionId)
//... other codes
}
public void SendMessage(string message)
{
foreach (var connectionId in _connectedClients)
{
// according to the logs
// android device connection id exists here
// and it works fine.
Clients.Client(connectionId).NewMessage(message);
}
}
}
When the android client connects to the server, On the OnConnected
method, the connection id will be stored in the _connectedClients
and it works fine.
In the SendMessage
method of the ChatHub
class, We have the android device connection id, and I'm sure that the android device is within the list
And here is my Andoird codes:
public class ChatActivity extends AppCompatActivity
{
// private fields
HubConnection connection;
HubProxy hub;
ClientTransport transport;
protected void onCreate(Bundle savedInstanceState) {
Logger logger = new Logger() {
@Override
public void log(String message, LogLevel logLevel) {
Log.e("SignalR", message);
}
};
Platform.loadPlatformComponent(new AndroidPlatformComponent());
connection = new HubConnection("192.168.1.100");
hub = connection.createHubProxy("chatHub"); // case insensitivity
transport = new LongPollingTransport(connection.getLogger());
// no difference when using this:
//transport = new ServerSentEventsTransport(connection.getLogger());
// this event never fired!
hub.subscribe(new Object() {
public void NewMessage(String message)
{
Log.d("<Debug", "new message received in subscribe"); // won't work!
}
}
// this event never fired!
hub.on("NewMessage", new SubscriptionHandler() {
@Override
public void run() {
Log.d("<Debug", "new message received in `on`"); // won't work!
}
});
// connect to the server that works fine.
SignalRFuture<Void> awaitConnection = connection.start(transport);
try {
awaitConnection.get(); // seems useless when using this or not!
}
catch (Exception ex) {
}
// this method works fine.
hub.invoke("sendMessage", "this is a test message to the server")
.done(new Action<Void>() {
@Override
public void run(Void aVoid) throws Exception {
Log.d("<Debug", "message sent."); // Works fine
}
});
}
}
In the above java code, invoking the sendMessage
on the server works fine and the server get the messages.
But the only problem is that the hub.on(...)
or hub.subscribe(...)
events are never be called by the server.
In a simple description, My app can send message, but can not receive message from the others.
Any suggestion will be appreciated.
The SignalR Java Client will run on Android API Level 16 and later.
Handle the disconnected event to display a message when an attempt to reconnect has timed out. In this scenario, the only way to re-establish a connection with the server again is to restart the SignalR connection by calling the Start method, which will create a new connection ID.
You does not provider parameters in your client-side which should be same as your side-site. The code should be below:
hub.on("NewMessage", new SubscriptionHandler1<String>() {
@Override
public void run(String message) {
Log.d("<Debug", "new message received in `on`");
}
},String.class); //do not forget say the String class in the end
For the futures this is the way I finally achieved the answer (please first read the question android codes):
public class ChatActivity extends AppCompatActivity
{
// private fields
HubConnection connection;
HubProxy hub;
ClientTransport transport;
protected void onCreate(Bundle savedInstanceState) {
Logger logger = new Logger() {
@Override
public void log(String message, LogLevel logLevel) {
Log.e("SignalR", message);
}
};
Platform.loadPlatformComponent(new AndroidPlatformComponent());
connection = new HubConnection("192.168.1.100");
hub = connection.createHubProxy("chatHub"); // case insensitivity
/* ****new codes here**** */
hub.subscribe(this);
transport = new LongPollingTransport(connection.getLogger());
/* ****new codes here**** */
connection.start(transport);
/* ****new codes here**** */
/* ****seems useless but should be here!**** */
hub.subscribe(new Object() {
@SuppressWarnings("unused")
public void newMessage(final String message, final String messageId, final String chatId,
final String senderUserId, final String fileUrl, final String replyToMessageId) {
}
});
/* ********************** */
/* ****new codes here**** */
/* **** the main method that I fetch data from server**** */
connection.received(new MessageReceivedHandler() {
@Override
public void onMessageReceived(final JsonElement json) {
runOnUiThread(new Runnable() {
public void run() {
JsonObject jsonObject = json.getAsJsonObject();
Log.e("<Debug>", "response = " + jsonObject.toString());
}
});
}
});
/* ********************** */
}
}
!important note:
The priority of the codes is important. this is how I fix my problem in this topic.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With