Как правильнее всего сделать переподключение к websocket?

Есть следующий код:

public class WsClient
{
    // WebSocket
    private ClientWebSocket ws = new ClientWebSocket();
    private UTF8Encoding encoder; // For websocket text message encoding.
    private const UInt64 MAXREADSIZE = 1 * 1024 * 1024;
    // Server address
    private Uri serverUri;

    // Queues
    public ConcurrentQueue<String> receiveQueue { get; }
    public BlockingCollection<ArraySegment<byte>> sendQueue { get; }
    // Threads
    private Thread receiveThread { get; set; }
    private Thread sendThread { get; set; }
    /// <summary>
    /// Initializes a new instance of the <see cref="T:WsClient"/> class.
    /// </summary>
    /// <param name="serverURL">Server URL.</param>
    public WsClient(string serverURL)
    {
        encoder = new UTF8Encoding();
        ws = new ClientWebSocket();
        serverUri = new Uri(serverURL);
        receiveQueue = new ConcurrentQueue<string>();
        receiveThread = new Thread(RunReceive);
        receiveThread.Start();
        sendQueue = new BlockingCollection<ArraySegment<byte>>();
        sendThread = new Thread(RunSend);
        sendThread.Start();
    }
    /// <summary>
    /// Method which connects client to the server.
    /// </summary>
    /// <returns>The connect.</returns>
    public async Task Connect()
    {
        Debug.WriteLine("Connecting to: " + serverUri);
        await ws.ConnectAsync(serverUri, CancellationToken.None);
        while (IsConnecting())
        {
            Debug.WriteLine("Waiting to connect...");
            Task.Delay(50).Wait();
        }
        Debug.WriteLine("Connect status: " + ws.State);
    }
    #region [Status]
    /// <summary>
    /// Return if is connecting to the server.
    /// </summary>
    /// <returns><c>true</c>, if is connecting to the server, <c>false</c> otherwise.</returns>
    public bool IsConnecting()
    {
        return ws.State == WebSocketState.Connecting;
    }
    /// <summary>
    /// Return if connection with server is open.
    /// </summary>
    /// <returns><c>true</c>, if connection with server is open, <c>false</c> otherwise.</returns>
    public bool IsConnectionOpen()
    {
        return ws.State == WebSocketState.Open;
    }
    #endregion
    #region [Send]
    /// <summary>
    /// Method used to send a message to the server.
    /// </summary>
    /// <param name="message">Message.</param>
    public void Send(string message)
    {
        byte[] buffer = encoder.GetBytes(message);
        //Debug.Log("Message to queue for send: " + buffer.Length + ", message: " + message);
        var sendBuf = new ArraySegment<byte>(buffer);
        sendQueue.Add(sendBuf);
    }
    /// <summary>
    /// Method for other thread, which sends messages to the server.
    /// </summary>
    private async void RunSend()
    {
        Debug.WriteLine("WebSocket Message Sender looping.");
        ArraySegment<byte> msg;
        while (true)
        {
            while (!sendQueue.IsCompleted)
            {
                msg = sendQueue.Take();
                //Debug.Log("Dequeued this message to send: " + msg);
                await ws.SendAsync(msg, WebSocketMessageType.Text, true /* is last part of message */, CancellationToken.None);
            }
        }
    }
    #endregion
    #region [Receive]
    /// <summary>
    /// Reads the message from the server.
    /// </summary>
    /// <returns>The message.</returns>
    /// <param name="maxSize">Max size.</param>
    private async Task<string> Receive(UInt64 maxSize = MAXREADSIZE)
    {
        // A read buffer, and a memory stream to stuff unknown number of chunks into:
        byte[] buf = new byte[4 * 1024];
        var ms = new MemoryStream();
        ArraySegment<byte> arrayBuf = new ArraySegment<byte>(buf);
        WebSocketReceiveResult chunkResult = null;
        if (IsConnectionOpen())
        {
            do
            {
                chunkResult = await ws.ReceiveAsync(arrayBuf, CancellationToken.None);
                ms.Write(arrayBuf.Array, arrayBuf.Offset, chunkResult.Count);
                //Debug.Log("Size of Chunk message: " + chunkResult.Count);
                if ((UInt64)(chunkResult.Count) > MAXREADSIZE)
                {
                    Console.Error.WriteLine("Warning: Message is bigger than expected!");
                }
            } while (!chunkResult.EndOfMessage);
            ms.Seek(0, SeekOrigin.Begin);
            // Looking for UTF-8 JSON type messages.

            byte[] msgBytes = arrayBuf.Skip(arrayBuf.Offset).Take(chunkResult.Count).ToArray();
            return Encoding.UTF8.GetString(msgBytes);
        }
        return "";
    }
    /// <summary>
    /// Method for other thread, which receives messages from the server.
    /// </summary>
    private async void RunReceive()
    {
        Debug.WriteLine("WebSocket Message Receiver looping.");
        string result;
        while (true)
        {
            //Debug.Log("Awaiting Receive...");
            result = await Receive();
            if (result != null && result.Length > 0)
            {
                receiveQueue.Enqueue(result);
            }
            else
            {
                Task.Delay(50).Wait();
            }
        }
    }
    #endregion

}

Вебсокет отлично работает, однако когда происходит что-то со связью, или сервер почему-то отвалился, то прием просто останавливается. Пробовал помещать все в try catch, но исключений никаких не возникает. Сейчас думаю проверять интервал времени как долго не приходили сообщения и делать переподключение. Но насколько мне известно если закрыть вебсокет, то заново пользоваться им уже нельзя. Как лучше всего сделать переподключение в данном случае?

Код чтения следующий:

while (true)
{
if (cqueue.TryDequeue(out rcvMsg))
{
//обработка данных
}
}

Ответы (0 шт):