1

The ASP.NET Core application uses websocket connection on the client side and Microsoft.AspNetCore.WebSockets.Server 0.1.0 (latest stable version on nuget as I know) on the server side. The simple sending code is

await _ws.SendAsync(new ArraySegment<byte>(arrbr), WebSocketMessageType.Text, true, ctk); 

the problem is this line throws error when it is a closed connection. I would like that method to return a Boolean if process was successful. I already check if the connection is open like this:

_ws.State == WebSocketState.Open 

But this does not work if user has unplugged the network cable or disconnected his device(almost all situations except closing the browsers).

As an extra, I do not know how to simulate network connection loss for one of two clients and I suppose WebSocketState is readonly, please warn me if I am wrong and I do not think shorter pings will solve this problem.
I have two ideas:

  1. I may use the sender code in a try catch block. (I am not comfortable with using try catch in production code)

  2. I may set interval on the client side, and ask the server like "what is new for me". I feel bad with this because it is away from being a websocket(closer to http).

Is there any way to fix this without using try catch? I know that this is not a qualified question but a qualified problem for me. I can share full code if needed.

Update 1

after using server-side logging:
While messaging is working well in production environment, I disconnect the client by unplugging the network cable and send data to the client. I use try catch and no catch. then i get this error.
This means I cant detect lost connection by using try catch. and i think i can solve this by handling this throw.
How can I handle this error?

update2

I have noticed that "Exceptions from an Async Void Method Can’t Be Caught with Catch" and "it's possible to use await in catch" since c# 6 link however I can not catch the throw.
I may try running synchronously await _ws.SendAsync(new ArraySegment<byte>(arrbr), WebSocketMessageType.Text, true, ctk).runsynchronously(); if I cant fix in this way

update3

running synchronously does not help. using try catch does not differ. as a result question, asp.net core websocket how to ping

update4

my log file when using Microsoft.aspnetcore.websockets.server 0.1.0

fail: Microsoft.AspNetCore.Server.Kestrel[13] Connection id "0HL1940BSEV8O": An unhandled exception was thrown by the application. System.IO.IOException: Unexpected end of stream at Microsoft.AspNetCore.WebSockets.Protocol.CommonWebSocket.<EnsureDataAvailableOrReadAsync>d__38.MoveNext()
my log file when using Microsoft.aspnetcore.websockets 1.0.0 fail: Microsoft.AspNetCore.Server.Kestrel[13] Connection id "0HL19H5R4CS21": An unhandled exception was thrown by the application. System.Net.WebSockets.WebSocketException (0x80004005): The remote party closed the WebSocket connection without completing the close handshake. ---> System.IO.IOException: Error -4077 ECONNRESET connection reset by peer ---> Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvException: Error -4077 ECONNRESET connection reset by peer

Community
  • 1
  • 1
ergen
  • 95
  • 2
  • 11
  • Ugh, I am totally not into reading that block of text. If you want help, you will need to make it readable, like using paragraphs. – gre_gor Dec 15 '16 at 15:12
  • actually i don't know how to paragraph too :} i will learn it after learning how to send data over websockets – ergen Dec 15 '16 at 18:51
  • 2
    http://stackoverflow.com/editing-help Making newlines and capitalisation isn't rocket science. – gre_gor Dec 15 '16 at 18:55
  • HAve you tried using a Try/Catch block ? –  Dec 17 '16 at 03:51
  • I tried trycatch too much. the problem occurs in server and only when the network cable has been unplugged. it works perfect locally. and I do not know how to simulate network loss locally – ergen Dec 17 '16 at 07:15
  • thank you. but I use aspnetcore websocket and it does not have a method named "poll". – ergen Dec 17 '16 at 23:50
  • It seems like this scenario is exactly what a try/catch block is intended to resolve. A network cable becoming unplugged is certainly *not* expected behavior, and a catch block should allow your application to recover. Without seeing more of your code it's not possible to debug any further. – Kjata30 Dec 21 '16 at 18:57
  • here is my code. http://csharppad.com/gist/e02082789c2795da2777d2fcbb168d30 i gave up and decided to use try catch, but it does not solve the problem. it looks like something else causes the error but that does not. i know this because of the application works well except unplugging the cable – ergen Dec 21 '16 at 19:21

2 Answers2

7

I might be missing something, but why can't wrap the sending operation in a method that returns bool in the following manner:

private async Task<bool> DoSend()
{
    bool success = true;

    try
    {
        await _ws.SendAsync(new ArraySegment<byte>(arrbr), WebSocketMessageType.Text, true, ctk);
    }
    catch (Exception ex)
    {
        // Do some logging with ex
        success = false;
    }

    return success;
}

I also suggest reading about Async All The Way, it should clear some of the confusion with async void, async Task and async Task<T>

Itay Podhajcer
  • 2,616
  • 2
  • 9
  • 14
  • I tried once more like you did and no luck, it always returns true, never catches. I use like catch { success=false; } not catch (exception ex){ success=false;} because of I do not need exception. I don't know if it matters. I will focus on "async all the way" – ergen Dec 19 '16 at 10:38
  • what type is _ws ? – Peter M. Dec 19 '16 at 11:42
  • what do you mean by type? it s an asp.net core application including "Microsoft.AspNetCore.WebSockets.Server": "0.1.0" – ergen Dec 19 '16 at 17:57
  • @ergen if it never catches, application will not crash. So where is your application crashing exactly? Can you provide a callstack? – Mateusz Krzaczek Dec 21 '16 at 16:13
  • I updated with the error logs. I am not sure about application crashes . if I send a message to the server after this error occurred, the client is closed and the server does not accept new socket connections until I recycle the application pool – ergen Dec 21 '16 at 17:53
  • additionally, here is full [class]. i can share more simplified version too but i do not think that is the problem. (http://csharppad.com/gist/e02082789c2795da2777d2fcbb168d30) – ergen Dec 21 '16 at 18:06
  • ah i can not edit my comment.sorry about it. line 87. it works the same way even if i don't use try catch there. – ergen Dec 21 '16 at 18:14
0

Until C# 6.0 to capture an exceptions from async methods you should use the ExceptionDispatchInfo type. Then the code will look like this:

private async Task<bool> DoSend()
{
    bool success = true;
    ExceptionDispatchInfo capturedException = null;

    try
    {
        await _ws.SendAsync(new ArraySegment<byte>(arrbr), WebSocketMessageType.Text, true, ctk);
    }
    catch (Exception ex)
    {
        capturedException = ExceptionDispatchInfo.Capture(ex);
    }

    if (capturedException != null)
    {
        await ExceptionHandler();

        if (needsThrow)
        {
            capturedException.Throw();
        }
    }

    success = capturedException == null;

    return success;
}
  • the problem is the code inside "catch" never works only "try". I can see that in log files. i think sendasync method thinks that sending is successful – ergen Sep 22 '17 at 19:21