WebSocket in UWP crashes with unknown reason

3

I wanna create communication with ASP.NET 5.0 under UWP using WebSockets.

Problem is on line "var response = await socket.ReceiveAsync.." With following error:

    System.Exception: Exception from HRESULT: 0x80072EFE
   at Windows.Networking.Sockets.MessageWebSocketMessageReceivedEventArgs.GetDataReader()
   at System.Net.WebSockets.WinRTWebSocket.OnMessageReceived(MessageWebSocket sender, MessageWebSocketMessageReceivedEventArgs args)

Code:

    async void Initialize(Uri serverAddress)
    {
        tokenSource = new CancellationTokenSource();
        token = tokenSource.Token;

        socket = new ClientWebSocket();

        try
        {
            await socket.ConnectAsync(serverAddress, token);

            await Task.Delay(1000);

            byte[] data = new byte[1024];

            var response = await socket.ReceiveAsync(new ArraySegment<byte>(data), token); // crashes with error HRESULT

            await Task.Delay(1000);

            if (response.EndOfMessage)
            {
                if (response.Count >= data.Length) // error
                    return;

                string json = Encoding.UTF8.GetString(data, 0, response.Count);

                PacketData packet = JsonConvert.DeserializeObject<PacketData>(json);
            }
        }
        catch (Exception ex)
        {
            if (socket != null)
            {
                socket.Dispose();

                socket = null;
            }
        }
    }

Is there something I do wrong? I tried to run it few times.. Once I get data, but it crashed on "object obj = ..." I checked json value and it was correct, I think it runs okay, but there is something I don't see what's causing crash.

Thanks

EDIT! New code using MessageWebSocket

Error while using code below: "The operation attempted to access data outside the valid range"

private void MSocket_MessageReceived(MessageWebSocket sender,               MessageWebSocketMessageReceivedEventArgs args)
    {
        byte[] data = new byte[1024];

        try
        {
            int length = 0;

            using (DataReader reader = args.GetDataReader())
            {
                reader.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf8;

                length = (int)reader.UnconsumedBufferLength; // If I create byte[] with length after then it throw same error like in original post.

                reader.ReadBytes(data); // Exception jump
            }

            string json = Encoding.UTF8.GetString(data, 0, length);

            PacketData packet = JsonConvert.DeserializeObject<PacketData>(json);
        }
        catch(Exception ex)
        {
            string a = ex.Message;
        }
    }

Init:

        mSocket = new MessageWebSocket();
        mSocket.Control.MessageType = SocketMessageType.Binary;
        mSocket.Control.MaxMessageSize = 1024;
        mSocket.MessageReceived += MSocket_MessageReceived;

EDIT 2! Find only working way, its creating array with static size. I don't know how to make it dynamicly. Help me please!

        private void MSocket_MessageReceived(MessageWebSocket sender, MessageWebSocketMessageReceivedEventArgs args)
    {
        byte[] data = new byte[27];

        try
        {
            int length = 0;

            using (DataReader reader = args.GetDataReader())
            {
                reader.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf8;

                length = (int)reader.UnconsumedBufferLength;

                reader.ReadBytes(data);
            }

            string json = Encoding.UTF8.GetString(data, 0, length);

            PacketData packet = JsonConvert.DeserializeObject<PacketData>(json);
        }
        catch(Exception ex)
        {
            string a = ex.Message;
        }
    }

EDIT3: Added Array.Resize(ref data, length), seems working, but I don't think is properly.

c#
asp.net-core
uwp
asp.net-core-mvc
asked on Stack Overflow Jan 19, 2016 by user1085907 • edited Jan 20, 2016 by user1085907

1 Answer

2

DataReader class has a ReadString method, we can use this method to get the received message without using byte[] like following:

private void MSocket_MessageReceived(MessageWebSocket sender, MessageWebSocketMessageReceivedEventArgs args)
{
    try
    {
        using (DataReader reader = args.GetDataReader())
        {
            reader.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf8;

            string json = reader.ReadString(reader.UnconsumedBufferLength);

            PacketData packet = JsonConvert.DeserializeObject<PacketData>(json);
        }
    }
    catch (Exception ex)
    {
        string a = ex.Message;
    }
}

If you still want to use byte[], you can try following code:

private void MSocket_MessageReceived(MessageWebSocket sender, MessageWebSocketMessageReceivedEventArgs args)
{
    byte[] data;

    try
    {
        int length = 0;

        using (DataReader reader = args.GetDataReader())
        {
            reader.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf8;

            length = (int)reader.UnconsumedBufferLength;
            data = new byte[length];

            reader.ReadBytes(data);
        }

        string json = System.Text.Encoding.UTF8.GetString(data, 0, length);

        PacketData packet = JsonConvert.DeserializeObject<PacketData>(json);
    }
    catch (Exception ex)
    {
        string a = ex.Message;
    }
}
answered on Stack Overflow Jan 21, 2016 by Jay Zuo

User contributions licensed under CC BY-SA 3.0