jammerware / margiebot

MargieBot is a .NET library designed to make building bots for Slack fast, easy, and fun.
MIT License
122 stars 42 forks source link

Here's a fix for MargieBotWebSocket to eliminate TrimStuffIDontKnowWhatItEvenIs #29

Open AronDavis opened 5 years ago

AronDavis commented 5 years ago

The Listen method is not properly using _webSocket.ReceiveAsync. You're getting bad JSON because you're not checking result.EndOfMessage. So you're getting a partial message and then the "leftovers" are the things you're trying to "trim".

Below is an example solution.

private async Task Listen()
{
    ArraySegment<Byte> buffer = new ArraySegment<byte>(new Byte[1024]);
    WebSocketReceiveResult result = null;

    while (_webSocket.State == WebSocketState.Open)
    {
        using (var ms = new MemoryStream())
        {
            do
            {
                result = await _webSocket.ReceiveAsync(buffer, CancellationToken.None);

                if (result.MessageType == WebSocketMessageType.Close)
                {
                    await _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None);
                    break;
                }
                else
                {
                    ms.Write(buffer.Array, buffer.Offset, result.Count);
                }
            }
            while (!result.EndOfMessage);

            ms.Seek(0, SeekOrigin.Begin);

            if (result.MessageType == WebSocketMessageType.Text)
            {
                using (var reader = new StreamReader(ms, Encoding.UTF8))
                {
                    var stringData = await reader.ReadToEndAsync();

#if DEBUG
                    Console.WriteLine($"Receive: {stringData}");
#endif

                    OnMessage?.Invoke(this, stringData);
                }
            }
        }
    }
}
AronDavis commented 5 years ago

31 is the pull request to implement this.