SignalR Core disconnects on Android client

Viewed 1052

I encountered connection issue while developing chat application on Android, it uses SignalR Core on the server side. Connection with server is established properly, client invokes for the first time server's method, server then invokes client's method successfully and in the end of execution of Android's listener connection drops. Each subsequent request to the server after the first one needs reconnection, becuase hubConnection.connectionState == HubConnectionState.DISCONNECTED. Reconnecting after each request is obviously bad. SignalR docs don't mention such case. What am I doing wrong?

Kotlin code:

override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)
    val hubConnection = HubConnectionBuilder.create("http://192.168.0.171:6000/chathub").build()
    hubConnection.start()

    hubConnection.on("MessageAdded", {msg ->
        chat_view_text.text = msg.from+": "+msg.content
    }, ChatMessage::class.java)

    chat_view_send_button.setOnClickListener{
        if (hubConnection.connectionState == HubConnectionState.CONNECTED){
            hubConnection.send("SendMessage", Message("android", "hello world"));
        }
    }
}

.NET code:

public class ChatHub : Hub<IClientChatActions>, IServerChatActions
{
    public override Task OnConnectedAsync()
    {
        Console.WriteLine("connected");
        return base.OnConnectedAsync();
    }

    public override Task OnDisconnectedAsync(Exception exception)
    {
        Console.WriteLine("disconnected");
        return base.OnDisconnectedAsync(exception);
    }

    public async Task SendMessage(Message msg)
    {
        await Clients.All.MessageAdded(msg);
    }
}
1 Answers

Android loses the connection while updating the UI this way ... Try to update your UI in the main thread using Kotlin Coroutines. Dispatchers.Main is the recommended dispatcher for performing UI-related events.

To do so, add to your build.gradle:

implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9'

In your activity.kt file, change it to something like:

private var job: Job = Job()
private val scope = CoroutineScope(job + Dispatchers.Main)
...
hubConnection.on("MessageAdded", {msg ->
    scope.launch(Dispatchers.Main) {
        chat_view_text.text = msg.from+": "+msg.content
    }
}, ChatMessage::class.java)
Related