zoukankan      html  css  js  c++  java
  • C# Net Core 使用 ClientWebSocket 实现 WebSocket 客户端

    C# 使用 ClientWebSocket 实现 WebSocket 客户端

    C# Net Core 使用 ClientWebSocket 实现 WebSocket 客户端

     Net Core 使用 ClientWebSocket 实现 WebSocket 客户端

    我们模仿HTML5的实现方式来重写一个C#类

    https://www.runoob.com/html/html5-websocket.html

    WebSocket 属性

    HTML5 描述 NET Core 描述
    readyState

    只读属性 readyState 表示连接状态,可以是以下值:

    0 - 表示连接尚未建立。

    1 - 表示连接已建立,可以进行通信。

    2 - 表示连接正在进行关闭。

    3 - 表示连接已经关闭或者连接不能打开。

    State WebSocket状态(点击看官方文档)
    bufferedAmount 只读属性 bufferedAmount 已被 send() 放入正在队列中等待传输,但是还没有发出的 UTF-8 文本字节数。 ------ 无此属性

    WebSocket 事件

    HTML5 描述 NET Core 描述
    onopen 连接建立时触发 OnOpen 连接建立时触发
    onmessage 客户端接收服务端数据时触发 OnMessage 客户端接收服务端数据时触发(暂时只支持文本消息)
    onerror 通信发生错误时触发 OnError

    通信发生错误时触发

    (如果处理消息中有错误事件没有处理,这里也会抛出并断开链接)

    onclose 连接关闭时触发 OnClose 连接关闭时触发

    WebSocket 方法

    HTML5 描述 NET Core 描述
    send() 使用连接发送数据 bool Send(string mess)
    bool Send(byte[] bytes)

    使用连接发送文本消息
    使用连接发送字节消息

    返回:是否尝试了发送

    close() 关闭连接

    void Close()

    void Close(WebSocketCloseStatus closeStatus, string statusDescription)

    关闭连接(关闭原因为用户手动关闭)
    关闭连接(自定义关闭原因)

     

     

     

     

     

     

    代码如下:

    创建文件WSocketClientHelp.cs:

    复制如下代码进去

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net.WebSockets;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
     
    namespace YingCaiEdu.Common.HttpHelp
    {
        public class WSocketClientHelp
        {
            ClientWebSocket ws = null;
            Uri uri = null;
            bool isUserClose = false;//是否最后由用户手动关闭
     
            /// <summary>
            /// WebSocket状态
            /// </summary>
            public WebSocketState? State { get => ws?.State; }
     
            /// <summary>
            /// 包含一个数据的事件
            /// </summary>
            public delegate void MessageEventHandler(object sender, string data);
            public delegate void ErrorEventHandler(object sender, Exception ex);
     
            /// <summary>
            /// 连接建立时触发
            /// </summary>
            public event EventHandler OnOpen;
            /// <summary>
            /// 客户端接收服务端数据时触发
            /// </summary>
            public event MessageEventHandler OnMessage;
            /// <summary>
            /// 通信发生错误时触发
            /// </summary>
            public event ErrorEventHandler OnError;
            /// <summary>
            /// 连接关闭时触发
            /// </summary>
            public event EventHandler OnClose;
     
            public WSocketClientHelp(string wsUrl)
            {
                uri = new Uri(wsUrl);
                ws = new ClientWebSocket();
            }
     
            /// <summary>
            /// 打开链接
            /// </summary>
            public void Open()
            {
                Task.Run(async () =>
                {
                    if (ws.State == WebSocketState.Connecting || ws.State == WebSocketState.Open)
                        return;
     
                    string netErr = string.Empty;
                    try
                    {
                        //初始化链接
                        isUserClose = false;
                        ws = new ClientWebSocket();
                        await ws.ConnectAsync(uri, CancellationToken.None);
     
                        if (OnOpen != null)
                            OnOpen(ws, new EventArgs());
     
                        Send("放映");
     
                        //全部消息容器
                        List<byte> bs = new List<byte>();
                        //缓冲区
                        var buffer = new byte[1024 * 4];
                        //监听Socket信息
                        WebSocketReceiveResult result = await ws.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
                        //是否关闭
                        while (!result.CloseStatus.HasValue)
                        {
                            //文本消息
                            if (result.MessageType == WebSocketMessageType.Text)
                            {
                                bs.AddRange(buffer.Take(result.Count));
     
                                //消息是否已接收完全
                                if (result.EndOfMessage)
                                {
                                    //发送过来的消息
                                    string userMsg = Encoding.UTF8.GetString(bs.ToArray(), 0, bs.Count);
     
                                    if (OnMessage != null)
                                        OnMessage(ws, userMsg);
     
                                    //清空消息容器
                                    bs = new List<byte>();
                                }
                            }
                            //继续监听Socket信息
                            result = await ws.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
                        }
                        ////关闭WebSocket(服务端发起)
                        //await ws.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
                    }
                    catch (Exception ex)
                    {
                        netErr = " .Net发生错误" + ex.Message;
     
                        if (OnError != null)
                            OnError(ws, ex);
     
                        //if (ws != null && ws.State == WebSocketState.Open)
                        //    //关闭WebSocket(客户端发起)
                        //    await ws.CloseAsync(WebSocketCloseStatus.Empty, ex.Message, CancellationToken.None);
                    }
                    finally
                    {
                        if (!isUserClose)
                            Close(ws.CloseStatus.Value, ws.CloseStatusDescription + netErr);
                    }
                });
     
            }
     
            /// <summary>
            /// 使用连接发送文本消息
            /// </summary>
            /// <param name="ws"></param>
            /// <param name="mess"></param>
            /// <returns>是否尝试了发送</returns>
            public bool Send(string mess)
            {
                if (ws.State != WebSocketState.Open)
                    return false;
     
                Task.Run(async () =>
                {
                    var replyMess = Encoding.UTF8.GetBytes(mess);
                    //发送消息
                    await ws.SendAsync(new ArraySegment<byte>(replyMess), WebSocketMessageType.Text, true, CancellationToken.None);
                });
     
                return true;
            }
     
            /// <summary>
            /// 使用连接发送字节消息
            /// </summary>
            /// <param name="ws"></param>
            /// <param name="mess"></param>
            /// <returns>是否尝试了发送</returns>
            public bool Send(byte[] bytes)
            {
                if (ws.State != WebSocketState.Open)
                    return false;
     
                Task.Run(async () =>
                {
                    //发送消息
                    await ws.SendAsync(new ArraySegment<byte>(bytes), WebSocketMessageType.Binary, true, CancellationToken.None);
                });
     
                return true;
            }
     
            /// <summary>
            /// 关闭连接
            /// </summary>
            public void Close()
            {
                isUserClose = true;
                Close(WebSocketCloseStatus.NormalClosure, "用户手动关闭");
            }
     
            public void Close(WebSocketCloseStatus closeStatus, string statusDescription)
            {
                Task.Run(async () =>
                {
                    try
                    {
                        //关闭WebSocket(客户端发起)
                        await ws.CloseAsync(closeStatus, statusDescription, CancellationToken.None);
                    }
                    catch (Exception ex)
                    {
     
                    }
     
                    ws.Abort();
                    ws.Dispose();
     
                    if (OnClose != null)
                        OnClose(ws, new EventArgs());
                });
            }
     
        }
     
    }

      

    使用方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net.WebSockets;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using YingCaiEdu.Common.HttpHelp;
     
    namespace YingCaiEdu.PPT.VstoPpt
    {
        public class PptSocket
        {
            private static PptSocket _this;
            public static PptSocket This
            {
                get
                {
                    if (_this == null)
                    {
                        _this = new PptSocket();
                    }
                    return _this;
                }
            }
     
            public WSocketClientHelp wSocketClient = new WSocketClientHelp("wss://baidu.com?user=ppt");
            public void Go()
            {
                wSocketClient.OnOpen -= WSocketClient_OnOpen;
                wSocketClient.OnMessage -= WSocketClient_OnMessage;
                wSocketClient.OnClose -= WSocketClient_OnClose;
                wSocketClient.OnError -= WSocketClient_OnError;
     
                wSocketClient.OnOpen += WSocketClient_OnOpen;
                wSocketClient.OnMessage += WSocketClient_OnMessage;
                wSocketClient.OnClose += WSocketClient_OnClose;
                wSocketClient.OnError += WSocketClient_OnError;
                wSocketClient.Open();
            }
     
            private void WSocketClient_OnError(object sender, Exception ex)
            {
     
            }
     
            private void WSocketClient_OnClose(object sender, EventArgs e)
            {
     
            }
     
            private void WSocketClient_OnMessage(object sender, string data)
            {
                //处理的消息错误将会忽略
                try
                {
                    if (data.Contains("放映"))
                    {
                        PptVstoApp.GetPptApp.SlideShowFromCurrent();
                    }
                }
                catch (Exception ex)
                {
     
                }
     
            }
     
            private void WSocketClient_OnOpen(object sender, EventArgs e)
            {
     
            }
        }
    }

      

    完成

    转自:https://www.cnblogs.com/ping9719/p/14821508.html

  • 相关阅读:
    拳击游戏(虚函数应用)
    虚函数的使用
    继承中的二义性归属问题
    继承的作用以及在子类中初始化所有数据的方法
    Exploring ES2016 Decorators
    Storage information for PWA application
    浏览器中常见网络协议介绍
    vuex所有核心概念完整解析State Getters Mutations Actions
    搭建一个webpack微服务器
    nodeJS接入微信公众平台开发
  • 原文地址:https://www.cnblogs.com/cuihongyu3503319/p/15224610.html
Copyright © 2011-2022 走看看