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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM