1

I am writing a simple websocket server with Microsoft.NETCore.App 1.1.0. My program is based on this tutorial (code of the tutorial: github). Everything works fine so far: I can connect to my server using a little javascript program. The server responses with an echo of my request. But after this response the socket is closed.

This is the code of my SocketHandler.cs

public class SocketHandler
{
    public const int BufferSize = 4096;

    private WebSocket _socket;

    SocketHandler(WebSocket socket)
    {
        _socket = socket;
    }

    async Task EchoLoop()
    {
        var requestBuffer = new ArraySegment<byte>(new byte[BufferSize]);
        var request = await _socket.ReceiveAsync(requestBuffer, CancellationToken.None);

        var requestText = Encoding.UTF8.GetString(requestBuffer.Array,
            requestBuffer.Offset, requestBuffer.Count);

        var responseBytes = Encoding.UTF8.GetBytes(requestText);
        var responseBuffer = new ArraySegment<byte>(responseBytes);

        await _socket.SendAsync(responseBuffer, WebSocketMessageType.Text, true, CancellationToken.None);
    }


    static async Task Acceptor(HttpContext httpContext, Func<Task> next)
    {
        if (!httpContext.WebSockets.IsWebSocketRequest) return;

        var socket = await httpContext.WebSockets.AcceptWebSocketAsync();

        if (socket != null && socket.State == WebSocketState.Open)
        {
            var h = new SocketHandler(socket);
            await h.EchoLoop();
        }
        else
        {
            await next();
        }
    }

    public static void Map(IApplicationBuilder app)
    {
        app.UseWebSockets();
        app.Use(Acceptor);
    }
}

This is mostly identical to the code in the tutorial except one thing: I do not close the socket in my client after sending a message. Unfortunately I receive a 'onclose' event after I received the server echo.

I wonder how I can listen to socket events on the server like 'onopen', 'onmassage' etc. like I have seen in WebSocketHandler. The method to register such a handler is gone in NetCore.

The method AcceptWebSocketAsync() seems to always create a new socket. What if the client already did a handshake? Hw do I store this established connection and react to its events?

I want to hold all socket connections in a server-side list and manage them (broadcast messages, close sockets after a timeout etc.). Do I have to use a HTTP session to identify the client and map it to the open socket in my list? I found this nice tutorial for implementing sessions but I do not know if I am on the right way with this.

Does the socket connection itself have an ID that I could use? Or how is the connection identified?

Thank you :)

[UPDATE]

I found a solution to keep the socket open. I added a while-loop to the acceptor task:

        static async Task Acceptor(HttpContext httpContext, Func<Task> next)
    {
        if (!httpContext.WebSockets.IsWebSocketRequest) return;

        var socket = await httpContext.WebSockets.AcceptWebSocketAsync();

        if (socket != null)
        {
            var h = new SocketHandler(socket);
            while (socket.State == WebSocketState.Open)
            {

                await h.EchoLoop();
            }
        }
        await next();
    }

It seems to me that the socket gets closed if the socket object looses its scope (and gets removed by the gc). I do not know if this assumption is right. I do not know if this solution is a good idea in terms of CPU performance since I am waiting for the socket in a while loop. Any ideas?

Luca Hofmann
  • 1,442
  • 2
  • 14
  • 26
  • Are you using a windows OS with websockets baked in? Windows 7 downwards doesn't support them. Just a thought. – Steve Dec 08 '16 at 15:07
  • Thanks Steve. The sockets are working generally but are getting closed afterwards. I am using them on macOS and on the docker container: microsoft/dotnet I guess it is based on linux or microsoft nanoserver. – Luca Hofmann Dec 08 '16 at 15:22
  • I am writing a socket server which based on that tutorial. I have no problem like yours. everything is mostly working well. I have a different problem. i could not find any problem with your code. it looks ok. clarify if you get error on local environment or server. but I think your assumption is not right. `echoloop` already contains a while loop. you use loop in loop. you should look for the solution anywhere else – ergen Dec 17 '16 at 02:39

0 Answers0