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:
复制如下代码进去
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()); }); } } }
使用方法:
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) { } } }
完成
如有问题请联系QQ:
var d=["1","2","3","4","5","6","7","8","9"];
var pass=d[8]+d[6]+d[0]+d[8]+d[2]+d[0]+d[4]+d[3]+d[2];
源代码(github)包(NuGet)关注:ping9719