0 votes
ago by (160 points)

Hi,

Im am trying to track down an issue with our websocket implementation and wondering if I am doing something wrong or it is an old version issue.

We currently use Rebex WebSocket (R6.5) for .NET 4.6-4.8 Version (6.0.8232.0)

To get at web socket messages we are using the following:-

ArraySegment<Byte> buffer = new ArraySegment<byte>(new Byte[8192]);
WebSocketReceiveResult result;
using ( var ms = new MemoryStream()) {
 do {
result = await m_floorEventSocket.ReceiveAsync(buffer, m_floorEventCancellation);
ms.Write(buffer.Array, buffer.Offset, result.Count);
} while (!result.EndOfMessage);
//Log some data here
//Removed our data processing to rule out any issues.
}

In our visual studio profiler, the memory just usage just continually increases.

I understand that the memory stream will not necessarily be immediately picked up by the GC, but I would have thought after a few hours and the memory having doubled, the GC would kick in.

Just wanted to check if this was the correct way to receive the messages and possibly check if this was an issue that has since been resolved and we need to update.

THanks,

Daniel.

Applies to: Rebex WebSocket

1 Answer

0 votes
ago by (150k points)

Hi, this should be fine, as long as you don't keep accumulating references to instances of any of those objects somewhere indefinitely, preventing GC from claiming them.

Have you tried running the application in debugger and taking a memory usage snapshot to find out what kind of objects are eating up your memory?

To make sure there is no obviously wrong behavior in Rebex WebSocket, I wrote the code below (where the server is just a simple echo server that sends back whatever it receives). I let it run the loop one million times, but did not observe an increase in memory usage over time.

var ws = new WebSocketClient();
ws.Connect(echoWebSocketServerWss);

var cancellation = new CancellationTokenSource();
string message = "hello".PadRight(16384, '!');

int runs = 0;
while (true)
{
    await ws.SendAsync(message);

    var buffer = new ArraySegment<byte>(new byte[8192]);
    WebSocketReceiveResult result;
    using (var ms = new MemoryStream())
    {
        do
        {
            result = await ws.ReceiveAsync(buffer, cancellation.Token);
            ms.Write(buffer.Array, buffer.Offset, result.Count);
        } while (!result.EndOfMessage);

        runs++;
        if ((runs % 1000) == 0) Console.WriteLine(runs);
    }
}

I then tried a different code, where a new instance of WebSocketClient and connection is created during each iteration:

int runs = 0;
while (true)
{
var ws = new WebSocketClient();
ws.Connect(echoWebSocketServerWss);

    var cancellation = new CancellationTokenSource();
    string message = "hello".PadRight(16384, '!');

    await ws.SendAsync(message);

    var buffer = new ArraySegment<byte>(new byte[8192]);
    WebSocketReceiveResult result;
    using (var ms = new MemoryStream())
    {
        do
        {
            result = await ws.ReceiveAsync(buffer, cancellation.Token);
            ms.Write(buffer.Array, buffer.Offset, result.Count);
        } while (!result.EndOfMessage);
    }

    await ws.CloseAsync(WebSocketCloseStatus.NormalClosure, "Bye.", cancellation.Token);

    runs++;
    if ((runs % 1000) == 0) Console.WriteLine(runs);
}

Expectedly, the memory usage was a bit higher, and each iteration took noticably longer due to repeated TLS negotiation, but again, memory usage kept hovering at the same level, and did not increase over time. I let this run 100 000 times.

I used .NET Framework 4.6-4.8 build of Rebex WebSocket R6.8 on Windows 11.

...