标签:scroll 字节 connect private rev 字节流 one fork exce
(1)建立在 TCP 协议之上,服务器端的实现比较容易。
(2)与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。
(3)数据格式比较轻量,性能开销小,通信高效。
(4)可以发送文本,也可以发送二进制数据。
(5)没有同源限制,客户端可以与任意服务器通信。
(6)协议标识符是ws
(如果加密,则为wss
),服务器网址就是 URL。
.Net 4.5及以后的版本才提供对websocket的支持,若项目所基于的.Net版本低于.Net 4.5且高于.Net 3.5,不妨尝试采用开源库websocket-sharp。
GitHub路径如下:https://github.com/sta/websocket-sharp 和 https://github.com/statianzo/Fleck
下面引用到 Fleck 和 WebSocketSharpFork
客户端
/// <summary> /// 客户端帮助类 作者:韩永健 /// </summary> public class WebSocketClientHelper { public delegate void ActionEventHandler(); public delegate void MessageEventHandler(string message); public delegate void ErrorEventHandler(Exception ex); /// <summary> /// 客户端打开连接时调用 /// </summary> public event ActionEventHandler OnOpen; /// <summary> /// 客户端关闭连接时调用 /// </summary> public event ActionEventHandler OnClose; /// <summary> /// 收到客户端信息时调用 /// </summary> public event MessageEventHandler OnMessage; /// <summary> /// 执行错误时调用 /// </summary> public event ErrorEventHandler OnError; /// <summary> /// 服务 /// </summary> private WebSocket client; /// <summary> /// 服务URL /// </summary> public string ServerUtl { private set; get; } /// <summary> /// 是否重连 /// </summary> public bool IsReConnection { set; get; } /// <summary> /// 重连间隔(毫秒) /// </summary> public int ReConnectionTime { set; get; } ? public WebSocketClientHelper(string serverUtl) { this.ServerUtl = serverUtl; client = new WebSocket(this.ServerUtl); client.OnOpen += new EventHandler(client_OnOpen); client.OnClose += new EventHandler<CloseEventArgs>(client_OnClose); client.OnMessage += new EventHandler<MessageEventArgs>(client_OnMessage); client.OnError += new EventHandler<ErrorEventArgs>(client_OnError); } ? public WebSocketClientHelper(string serverUtl, bool isReConnection, int reConnectionTime = 1000) : this(serverUtl) { this.IsReConnection = isReConnection; this.ReConnectionTime = reConnectionTime; } ? public void client_OnOpen(object sender, EventArgs e) { try { Console.WriteLine("Open!"); if (OnOpen != null) OnOpen(); } catch (Exception ex) { //记录日志 if (OnError != null) OnError(ex); else throw ex; } } ? public void client_OnClose(object sender, CloseEventArgs e) { try { Console.WriteLine("Close!"); if (OnClose != null) OnClose(); //掉线重连 if (IsReConnection) { Thread.Sleep(ReConnectionTime); Start(); } } catch (Exception ex) { //记录日志 if (OnError != null) OnError(ex); else throw ex; } } ? public void client_OnMessage(object sender, MessageEventArgs e) { try { Console.WriteLine("socket收到信息:" + e.Data); if (OnMessage != null) OnMessage(e.Data); } catch (Exception ex) { //记录日志 if (OnError != null) OnError(ex); //else // throw ex; } } ? public void client_OnError(object sender, ErrorEventArgs e) { if (OnError != null) OnError(e.Exception); //记录日志 //掉线重连 if (IsReConnection) { Thread.Sleep(ReConnectionTime); Start(); } } /// <summary> /// 启动服务 /// </summary> public void Start() { try { client.ConnectAsync(); } catch (Exception ex) { //日志 if (OnError != null) OnError(ex); else throw ex; } } /// <summary> /// 关闭服务 /// </summary> public void Close() { try { IsReConnection = false; client.CloseAsync(); } catch (Exception ex) { //记录日志 if (OnError != null) OnError(ex); else throw ex; } } /// <summary> /// 发送信息 /// </summary> public void Send(string message) { try { client.Send(message); } catch (Exception ex) { //记录日志 if (OnError != null) OnError(ex); else throw ex; } } /// <summary> /// 发送信息 /// </summary> public void Send(byte[] message) { try { client.Send(message); } catch (Exception ex) { //记录日志 if (OnError != null) OnError(ex); else throw ex; } } }
/// <summary> /// WebSocket服务辅助类 作者韩永健 /// </summary> public class WebSocketServerHelper { /// <summary> /// 客户端信息 /// </summary> public class ClientData { /// <summary> /// IP /// </summary> public string IP { get; set; } /// <summary> /// 端口号 /// </summary> public int Port { get; set; } } public delegate void ActionEventHandler(string ip, int port); public delegate void MessageEventHandler(string ip, int port, string message); public delegate void BinaryEventHandler(string ip, int port, byte[] message); public delegate void ErrorEventHandler(string ip, int port, Exception ex); /// <summary> /// 客户端打开连接时调用 /// </summary> public event ActionEventHandler OnOpen; /// <summary> /// 客户端关闭连接时调用 /// </summary> public event ActionEventHandler OnClose; /// <summary> /// 收到客户端信息时调用 /// </summary> public event MessageEventHandler OnMessage; /// <summary> /// 收到客户端信息时调用 /// </summary> public event BinaryEventHandler OnBinary; /// <summary> /// 执行错误时调用 /// </summary> public event ErrorEventHandler OnError; /// <summary> /// 服务 /// </summary> private Fleck.WebSocketServer server; /// <summary> /// socket列表 /// </summary> private Dictionary<string, IWebSocketConnection> socketList = new Dictionary<string, IWebSocketConnection>(); private List<ClientData> clientList = new List<ClientData>(); /// <summary> /// 客户端ip列表 /// </summary> public List<ClientData> ClientList { get { return clientList; } } /// <summary> /// 服务URL /// </summary> public string ServerUtl { private set; get; } ? public WebSocketServerHelper(string serverUtl) { this.ServerUtl = serverUtl; server = new Fleck.WebSocketServer(this.ServerUtl); } /// <summary> /// 启动服务 /// </summary> public void Start() { server.Start(socket => { try { socket.OnOpen = () => SocketOpen(socket.ConnectionInfo.ClientIpAddress, socket.ConnectionInfo.ClientPort); socket.OnClose = () => SocketClose(socket.ConnectionInfo.ClientIpAddress, socket.ConnectionInfo.ClientPort); socket.OnMessage = message => SocketMessage(socket.ConnectionInfo.ClientIpAddress, socket.ConnectionInfo.ClientPort, message); socket.OnBinary = message => SocketBinary(socket.ConnectionInfo.ClientIpAddress, socket.ConnectionInfo.ClientPort, message); socket.OnError = ex => SocketError(socket.ConnectionInfo.ClientIpAddress, socket.ConnectionInfo.ClientPort, ex); socketList.Add(socket.ConnectionInfo.ClientIpAddress + ":" + socket.ConnectionInfo.ClientPort, socket); ClientList.Add(new ClientData() { IP = socket.ConnectionInfo.ClientIpAddress, Port = socket.ConnectionInfo.ClientPort }); } catch (Exception ex) { } }); } ? /// <summary> /// Socket错误 /// </summary> private void SocketError(string ip, int port, Exception ex) { Console.WriteLine("Error!" + ip + ":" + port + " " + ex); socketList.Remove(ip + ":" + port); ClientList.RemoveAll(m => m.IP == ip && m.Port == port); if (OnError != null) OnError(ip, port, ex); //else // throw ex; } ? /// <summary> /// Socket打开连接 /// </summary> private void SocketOpen(string ip, int port) { try { Console.WriteLine("Open!" + ip + ":" + port); if (OnOpen != null) OnOpen(ip, port); } catch (Exception ex) { if (OnError != null) OnError(ip, port, ex); else throw ex; } } ? /// <summary> /// Socket关闭连接 /// </summary> private void SocketClose(string ip, int port) { try { Console.WriteLine("Close!" + ip + ":" + port); socketList.Remove(ip + ":" + port); ClientList.RemoveAll(m => m.IP == ip && m.Port == port); if (OnClose != null) OnClose(ip, port); } catch (Exception ex) { if (OnError != null) OnError(ip, port, ex); else throw ex; } } /// <summary> /// 接收到的信息 /// </summary> private void SocketBinary(string ip, int port, byte[] message) { try { Console.WriteLine("socket收到信息:byte[]"); if (OnBinary != null) OnBinary(ip, port, message); } catch (Exception ex) { if (OnError != null) OnError(ip, port, ex); else throw ex; } } /// <summary> /// 接收到的信息 /// </summary> private void SocketMessage(string ip, int port, string message) { try { Console.WriteLine("socket收到信息:" + message + " " + ip + ":" + port); if (OnMessage != null) OnMessage(ip, port, message); } catch (Exception ex) { if (OnError != null) OnError(ip, port, ex); else throw ex; } } /// <summary> /// 发送信息(单客户端) /// </summary> public void Send(string ip, int port, string message) { try { socketList[ip + ":" + port].Send(message); } catch (Exception ex) { if (OnError != null) OnError(ip, port, ex); else throw ex; } } /// <summary> /// 发送信息(单客户端) /// </summary> public void Send(string ip, int port, byte[] message) { try { socketList[ip + ":" + port].Send(message); } catch (Exception ex) { if (OnError != null) OnError(ip, port, ex); else throw ex; } } /// <summary> /// 发送信息(所有客户端) /// </summary> public void SendAll(string message) { for (int i = 0; i < socketList.Count; i++) { var item = socketList.ElementAt(i); try { item.Value.Send(message); } catch (Exception ex) { if (OnError != null) OnError(item.Value.ConnectionInfo.ClientIpAddress, item.Value.ConnectionInfo.ClientPort, ex); else throw ex; } } } /// <summary> /// 发送信息(所有客户端) /// </summary> public void SendAll(byte[] message) { for (int i = 0; i < socketList.Count; i++) { var item = socketList.ElementAt(i); try { item.Value.Send(message); } catch (Exception ex) { if (OnError != null) OnError(item.Value.ConnectionInfo.ClientIpAddress, item.Value.ConnectionInfo.ClientPort, ex); else throw ex; } } } }
标签:scroll 字节 connect private rev 字节流 one fork exce
原文地址:https://www.cnblogs.com/nanguoyezi/p/9351555.html