WebSocket 协议用于完全双工的双向通信。这种通信,一般在浏览器和Web服务器之间进行,但仅交流那些支持使用WebSocket协议的客户端信息。WebSocket维持一个打开的连接。
Tcp发送是字节流,而WebSocket是在服务器和客户端之间来回发送信息。
HTTP协议做不到服务器主动向客户端推送消息,为此,HTTP使用是,长轮询。
WebSocket 特点:

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

最新文章

  1. hdu 3632 A Captivating Match(区间dp)
  2. oracle性能优化之表设计
  3. 粒子拼字效果(getImageData方法)
  4. 贪心算法-最小生成树Kruskal算法和Prim算法
  5. centos+nginx从零开始配置负载均衡
  6. java新项目的eclipse统一配置记录
  7. win10搭建代理服务器实现绕过校园网的共享限制--从入门到放弃
  8. chroot详解
  9. spark1.6配置sparksql 的元数据存储到postgresql中
  10. 查看Linux软件信息
  11. Timed Code
  12. 转:Android 设置屏幕不待机
  13. 第二百六十九天 how can I 坚持
  14. DevExpress XtraReports 入门三 创建 Master-Detail(主/从) 报表
  15. poj_3461: Oulipo
  16. 使用GDB调试将符号表与程序分离后的可执行文件
  17. [转] 那些在使用webpack时踩过的坑
  18. python页面解析_beautifulsoup试玩
  19. 转!!spring @component 详解 默认初始化bean的名字 VNumberTask类 就是 VNumberTask
  20. CentOS6升级Python2.6到3.7,错误处理[No module named &#39;_ctypes&#39;]

热门文章

  1. redis 集群引出hash一致性算法
  2. CentOS 7 + MySql 中文乱码解决方案
  3. linux-基础命令篇-01
  4. composer 自动加载(php-amqplib)
  5. yeoman 前端自动化构建工具 generator-fountain-webapp
  6. 本地搭建Apache Tomcat服务器
  7. 利用map和reduce编写一个str2float函数,把字符串&#39;123.456&#39;转换成浮点数123.456:
  8. 【webpack学习笔记】a07-代码分离
  9. 记录Linux CentOS 7系统完整部署Docker容器环境教程
  10. LeetCode 160 相交链表