App crashes when trying to connect to SignalR server after disconnecting it

こ雲淡風輕ζ 提交于 2019-12-08 11:26:10

问题


I'm building a Xamarin Android app that uses SignalR for the purpose of real time chat. The app crashes when I try to connect to the server again after I disconnect it and when the app relaunches, it connects fine. I have a singleton class that used for the same reference across my solution. The singleton class has the following method to connect to the server:

public async Task<string> StartConnection()
    {
        hubConnection.Headers.Add("User-Agent", "mobile");
        hubConnection.Headers.Add("username", loggedUser);
        try
        {
            await hubConnection.Start();
            return "Connected..";
        }
        catch (Exception e)
        {
            return e.Message;
        }

    }

Following method disconnects the connection:

public void StopConnection()
    {
        hubConnection.Stop();

    }

The connection is started in the MainActivity of the app as shown in below:

      Task.Factory.StartNew(async () =>
        {
            await SignalRClientHelper.StartConnection();
            SignalRClientHelper.InvokeGetPendingConversations(loggedonuser.UserName);

        });

The connection is disconnected when the user is logged out as shown below:

SignalRClientHelper.StopConnection();

The client can connect to the signalR server for the first time without any problem but when they logout and login in to the app again, the app crashes when trying to server the second time. Here's the error log:

    ava.lang.RuntimeException: java.lang.reflect.InvocationTargetException
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:747)
    at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.reflect.InvocationTargetException
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:980)
    ... 2 more
Caused by: md52ce486a14f4bcd95899665e9d932190b.JavaProxyThrowable: System.InvalidOperationException: Data cannot be sent because the connection is in the disconnected state. Call start before sending any data.
  at Microsoft.AspNet.SignalR.Client.Connection.Send (System.String data) [0x0001e] in <filename unknown>:0 
  at Microsoft.AspNet.SignalR.Client.Hubs.HubProxy.Invoke[TResult,TProgress] (System.String method, System.Action`1 onProgress, System.Object[] args) [0x000e1] in <filename unknown>:0 
  at Microsoft.AspNet.SignalR.Client.Hubs.HubProxy.Invoke[T] (System.String method, System.Object[] args) [0x00000] in <filename unknown>:0 
  at Microsoft.AspNet.SignalR.Client.Hubs.HubProxy.Invoke (System.String method, System.Object[] args) [0x00000] in <filename unknown>:0 
  at Yourtime.SignalRClientHelper+<InvokeSendMessage>d__11.MoveNext () [0x0000d] in <filename unknown>:0 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <filename unknown>:0 
  at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<ThrowAsync>m__0 (System.Object state) [0x00000] in <filename unknown>:0 
  at Android.App.SyncContext+<Post>c__AnonStorey0.<>m__0 () [0x00000] in <filename unknown>:0 
  at Java.Lang.Thread+RunnableImplementor.Run () [0x0000b] in <filename unknown>:0 
  at Java.Lang.IRunnableInvoker.n_Run (IntPtr jnienv, IntPtr native__this) [0x00009] in <filename unknown>:0 
  at (wrapper dynamic-method) System.Object:44f67f43-349f-4a1b-8234-1604bc812b68 (intptr,intptr)
    at mono.java.lang.RunnableImplementor.n_run(Native Method)
    at mono.java.lang.RunnableImplementor.run(RunnableImplementor.java:29)
    at android.os.Handler.handleCallback(Handler.java:605)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4511)

Does anyone have any idea what might be wrong here?


回答1:


SignalR disconnection is bit buggy IMO, but your error clearly says you are trying to invoke something when in disconnected state.

I suggest you change the way you connect/disconnect as follows:

Disconnect

var connectionToDispose = _connection; // _connection is the current connection
_connection = null;
_proxy = null;

// connection disposing can block the UI thread for about 20 seconds
// this doesn´t always happen but just in case we run it on a new thread
Task.Run(() =>
{
    try
    {
        connectionToDispose.Dispose();
    }
    catch (Exception ex)
    {
        _tracer?.WriteLine($"[{_className}] Connection could not be disposed: {ex.Message}");
    }
});

Connect

if (_connection != null)
{
    return false;
}

// always create a new Hub
_connection = new HubConnection(_endpointUri);
// TODO add headers
// TODO create proxy again and subscribe to server events (proxy.On...), etc

try
{
    _tracer?.WriteLine($"[{_className}] CONNECTING...");
    await _connection.Start();

    return true;
}
catch (Exception ex)
{
    _tracer?.WriteLine($"[{_className}] CONNECTION START ERROR: {ex.Message}");
    return false;
}

Just for reference, take a look a this class. I´ve used in an app that connects/disconnects many times with no issues. You can take some ideas from it.



来源:https://stackoverflow.com/questions/38158042/app-crashes-when-trying-to-connect-to-signalr-server-after-disconnecting-it

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!