c# - UWP 中的 WebSocket 因未知原因崩溃

标签 c# asp.net-core uwp asp.net-core-mvc

我想在 UWP 下使用 WebSockets 创建与 ASP.NET 5.0 的通信。

问题在线“var response = await socket.ReceiveAsync..” 出现以下错误:

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

代码:

    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;
            }
        }
    }

我做错了什么吗? 我尝试运行它几次。一旦我获得数据,但它在“object obj = ...”上崩溃了我检查了 json 值并且它是正确的,我认为它运行正常,但有些东西我没有看到是什么导致崩溃。

谢谢

编辑! 使用 MessageWebSocket 的新代码

使用以下代码时出错:“操作试图访问有效范围之外的数据”

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;
        }
    }

初始化:

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

编辑 2! 找到唯一的工作方式,它创建静态大小的数组。我不知道如何动态地制作它。请帮助我!

        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;
        }
    }

编辑3: 添加了 Array.Resize(ref data, length),似乎有效,但我认为不合适。

最佳答案

DataReader 类有一个 ReadString方法,我们可以使用此方法获取接收到的消息,而无需使用 byte[],如下所示:

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;
    }
}

如果你还想使用byte[],你可以试试下面的代码:

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;
    }
}

关于c# - UWP 中的 WebSocket 因未知原因崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34883358/

相关文章:

asp.net-core - IWebHost WebHostBuilder BuildWebHost和有什么不一样

asp.net-mvc - 在 Asp.Net 5 中确保 SSL 的正确方法是什么

c# - 无法启动服务挂载被拒绝 '/usr/local/share/dotnet/sdk/NuGetFallbackFolder\r\n' 不是来自 macos X 的共享并且 docker 不知道

c# - Stackpanel 中的用户控件失去焦点

c# - 如何从 C# 文件中加载 UWP 格式的图像

c# - 在 Active Directory 中的计算机上获取上次登录时间

javascript - 使用信号器更新数据库更改时如何刷新 View

c# - 我应该什么时候处理数据上下文

c# - "existing connection was forcibly closed"在 .NET 2.0 中发送电子邮件时出错

c# - HttpClient 在上传前读取整个文件。 UWP