Xamarin(PCL) - 信号R - System.InvalidOperationExceptionConnection在收到调用结果之前开始重新连接

时间:2017-07-25 10:09:43

标签: xamarin xamarin.ios xamarin.android signalr signalr.client

我收到System.InvalidOperationExceptionConnection开始重新连接之前调用结果收到异常有时与Signal R聊天,我在Xamarin项目的PCL中使用Signal R客户端

这是聊天服务类 -

public class ChatService : IChatService
{
    private IHubProxy _hubProxy;
    private HubConnection _hubConnection;
    private readonly IMobileServiceClient _mobileClient;
    private readonly IInsightsService _insightsService;
    private readonly IChatMessageRepository _chatRepository;

    public ChatService(IMobileServiceClient mobileClient, IInsightsService insightsService, IChatMessageRepository chatRepository)
    {
        _insightsService = insightsService;
        _mobileClient = mobileClient;
        _chatRepository = chatRepository;
    }

    public event EventHandler<ChatMessage> MessageReceived;

    public async Task Connect(bool dismissCurrentConnection = false)
    {
        try
        {
            if (!CrossConnectivity.Current.IsConnected)
            {
                return;
            }

            // Always create a new connection to avoid SignalR close event delays
            if (_hubConnection != null)
            {
                if (!dismissCurrentConnection)
                {
                    return;
                }

                _hubConnection.StateChanged -= OnConnectionStateChangedHandler;
                _hubConnection.Reconnected -= OnReconnectedHandler;
                // DON´T call connection.Dispose() or it may block for 20 seconds
                _hubConnection = null;
                _hubProxy = null;
            }

            _hubConnection = new HubConnection(Identifiers.Environment.ChatUrl);
            // connection.TransportConnectTimeout = TimeSpan.FromSeconds(5);
            _hubConnection.TraceWriter = new DebugTextWriter("SignalR");
            _hubConnection.TraceLevel = TraceLevels.All;
            _hubConnection.StateChanged += OnConnectionStateChangedHandler;
            _hubConnection.Reconnected += OnReconnectedHandler;

            if (_mobileClient.CurrentUser == null)
                throw new Exception("MobileClient.CurrentUser null. You have to login to Azure Mobile Service first.");

            _hubConnection.Headers[HttpHeaders.XZumoAuth] = _mobileClient.CurrentUser.MobileServiceAuthenticationToken;

            _hubProxy = _hubConnection.CreateHubProxy(Identifiers.ChatHubName);

            _hubProxy.On<ChatMessage>("addMessage", message =>
            {
                MessageReceived?.Invoke(this, message);
            });

            if (_hubConnection.State == ConnectionState.Disconnected)
            {
                await _hubConnection.Start();
            }
        }
        catch (Exception ex)
        {
            _insightsService.ReportException(ex);
        }
    }

    private async void OnConnectionStateChangedHandler(StateChange change)
    {
        if (_mobileClient?.CurrentUser != null && change.NewState == ConnectionState.Disconnected && CrossConnectivity.Current.IsConnected)
        {
            // SignalR doesn´t do anything after disconnected state, so we need to manually reconnect
            await Connect(true);
        }
    }

    private void OnReconnectedHandler()
    {
        Debug.WriteLine("[SignalR] SignalR Reconnected to Hub: {0}", Identifiers.ChatHubName);
    }

    public async Task SendMessage(ChatMessage message)
    {
        try
        {               
            if (_hubConnection.State == ConnectionState.Disconnected)
            {
                await Connect(true);
            }

            await _hubProxy.Invoke("Send", message);
        }
        catch (Exception ex)
        {
            try
            {
                await _chatRepository.InsertAsync(message);
            }
            catch (Exception ex2)
            {
                _insightsService.ReportException(ex);
                _insightsService.ReportException(ex2);
                throw ex;
            }
        }
    }

    public async Task JoinChatRoom(string chatRoomId)
    {
        try
        {
            if (_hubConnection.State == ConnectionState.Disconnected)
            {
                await Connect(true);
            }

            await _hubProxy.Invoke("JoinChatRoom", chatRoomId);
        }
        catch (Exception ex)
        {
            _insightsService.ReportException(ex);
        }
    }

    public async Task LeaveChatRoom(string chatRoomId)
    {
        try
        {
            if (_hubConnection.State == ConnectionState.Disconnected)
            {
                await Connect(true);
            }

            await _hubProxy.Invoke("LeaveChatRoom", chatRoomId);
        }
        catch (Exception ex)
        {
            _insightsService.ReportException(ex);
        }
    }

    public void Disconnect()
    {
        try
        {
            if (_hubConnection != null && _hubConnection.State != ConnectionState.Disconnected)
                _hubConnection.Stop();
        }
        catch (Exception ex)
        {
            _insightsService.ReportException(ex);
        }
    }
}

如何防止和捕获此异常?这并非总是如此

0 个答案:

没有答案