目录

一、简介

二、服务端

1.新建项目

2.WebSocketHelper

3.Program

三、客户端

1.html

2.Winform

结束


一、简介

WebSocket 是一种在单个TCP连接上进行全双工通信的协议。WebSocket 通信协议于2011年被IETF定为标准RFC 6455,并由RFC7936补充规范。WebSocket API也被W3C定为标准。

WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

Websocket 用法和 TCP 协议差不多,在这里我用 C# 写服务器端, html 和 winform 作为客户端。

二、服务端

1.新建项目

新建一个控制台项目

在 NuGet 引入  Fleck 插件

2.WebSocketHelper

新建 WebSocketHelper.cs

代码

using Fleck;namespace WebSocket
{internal class WebSocketHelper{//客户端url以及其对应的Socket对象字典IDictionary<string, IWebSocketConnection> dic_Sockets = new Dictionary<string, IWebSocketConnection>();//创建一个 websocket ,0.0.0.0 为监听所有的的地址WebSocketServer server = new WebSocketServer("ws://0.0.0.0:30000");//打开连接委托public delegate void _OnOpen(string ip);public event _OnOpen OnOpen;//关闭连接委托public delegate void _OnClose(string ip);public event _OnClose OnClose;//当收到消息public delegate void _OnMessage(string ip, string msg);public event _OnMessage OnMessage;/// <summary>/// 初始化/// </summary>private void Init(){//出错后进行重启server.RestartAfterListenError = true;//开始监听server.Start(socket =>{//连接建立事件socket.OnOpen = () =>{//获取客户端网页的urlstring clientUrl = socket.ConnectionInfo.ClientIpAddress + ":" + socket.ConnectionInfo.ClientPort;dic_Sockets.Add(clientUrl, socket);if (OnOpen != null) OnOpen(clientUrl);Console.WriteLine(DateTime.Now.ToString() + " | 服务器:和客户端:" + clientUrl + " 建立WebSock连接!");};//连接关闭事件socket.OnClose = () =>{string clientUrl = socket.ConnectionInfo.ClientIpAddress + ":" + socket.ConnectionInfo.ClientPort;//如果存在这个客户端,那么对这个socket进行移除if (dic_Sockets.ContainsKey(clientUrl)){dic_Sockets.Remove(clientUrl);if (OnClose != null) OnClose(clientUrl);}Console.WriteLine(DateTime.Now.ToString() + " | 服务器:和客户端:" + clientUrl + " 断开WebSock连接!");};//接受客户端网页消息事件socket.OnMessage = message =>{string clientUrl = socket.ConnectionInfo.ClientIpAddress + ":" + socket.ConnectionInfo.ClientPort;Receive(clientUrl, message);if (OnMessage != null) OnMessage(clientUrl, message);};});}/// <summary>/// 向客户端发送消息/// </summary>/// <param name="webSocketConnection">客户端实例</param>/// <param name="message">消息内容</param>public void Send(string clientUrl, string message){IWebSocketConnection webSocketConnection = GetUserSocketInstance(clientUrl);if (webSocketConnection != null){if (webSocketConnection.IsAvailable){webSocketConnection.Send(message);}}}/// <summary>/// 接收消息/// </summary>/// <param name="clientUrl"></param>/// <param name="message"></param>private void Receive(string clientUrl, string message){Console.WriteLine(DateTime.Now.ToString() + " | 服务器:【收到】来客户端:" + clientUrl + "的信息:\n" + message);}/// <summary>/// 获取用户实例/// </summary>/// <param name="clientUrl">用户的地址</param>public IWebSocketConnection GetUserSocketInstance(string clientUrl){if (dic_Sockets.ContainsKey(clientUrl))return dic_Sockets[clientUrl];elsereturn null;}/// <summary>/// 关闭某一个用户的连接/// </summary>/// <param name="clientUrl"></param>public void CloseUserConnect(string clientUrl){IWebSocketConnection webSocketConnection = GetUserSocketInstance(clientUrl);if (webSocketConnection != null)webSocketConnection.Close();}/// <summary>/// 关闭与客户端的所有的连接/// </summary>public void CloseAllConnect(){foreach (var item in dic_Sockets.Values){if (item != null){item.Close();}}}public WebSocketHelper(){Init();}}
}

3.Program

目前并没有写入太多功能,只是加了控制台输入文字,然后转发给所有连接的用户

代码

using WebSocket;namespace WebSocketNet6
{internal class Program{private static List<string> IPList = new List<string>();private static WebSocketHelper WebSocketHelpers = new WebSocketHelper();static void Main(string[] args){WebSocketHelpers.OnOpen += WebSocketHelper_OnOpen;WebSocketHelpers.OnClose += WebSocketHelper_OnClose;WebSocketHelpers.OnMessage += WebSocketHelper_OnMessage;while (true){//监听控制台的输入string? contetn = Console.ReadLine();if (contetn != null){Relay(contetn);if (contetn.Equals("q")){WebSocketHelpers.CloseAllConnect();Console.WriteLine("关闭所有客户端的连接");break;}}Thread.Sleep(10);}}#region WebSocket回调//当收到消息private static void WebSocketHelper_OnMessage(string ip, string msg){for (int i = 0; i < IPList.Count; i++){if (IPList[i] != ip){WebSocketHelpers.Send(IPList[i], msg);}}}//当客户端断开连接private static void WebSocketHelper_OnClose(string ip){if (IPList.Contains(ip)){IPList.Remove(ip);}}//当客户端连接上服务器private static void WebSocketHelper_OnOpen(string ip){if (!IPList.Contains(ip)){IPList.Add(ip);}}#endregion//转发所有客户端private static void Relay(string content){if (IPList.Count == 0)  return;for (int i = 0; i < IPList.Count; i++){WebSocketHelpers.Send(IPList[i], content);}}}
}

三、客户端

1.html


<!DOCTYPE  HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head><title>websocket client</title><script type="text/javascript">var start = function () {var inc = document.getElementById('incomming');var wsImpl = window.WebSocket || window.MozWebSocket;var form = document.getElementById('sendForm');var input = document.getElementById('sendText');inc.innerHTML += "连接服务器..<br/>";// 创建一个新的websocket并连接window.ws = new wsImpl('ws://localhost:30000/');// 当数据来自服务器时,将调用此方法ws.onmessage = function (evt) {inc.innerHTML += ("[来自服务器的消息] " + evt.data + '<br/>');console.log("[来自服务器的消息] " + evt.data);};// 当建立连接时,将调用此方法ws.onopen = function () {inc.innerHTML += '已建立连接.. <br/>';};// 当连接关闭时,将调用此方法ws.onclose = function () {inc.innerHTML += '连接已关闭.. <br/>';}form.addEventListener('submit', function (e) {e.preventDefault();var val = input.value;ws.send(val);input.value = "";});}window.onload = start;</script>
</head>
<body><form id="sendForm"><span>输入内容按回车发送消息</span> <br/><input id="sendText" placeholder="Text to send" /></form><pre id="incomming"></pre>
</body>
</html>

在本地新建一个 文本文档,将名字改为 index.html ,然后将上面的代码复制进去。

先打开上面的 Webscoket 服务器,用浏览器打开 index.html,

然后服务器端就会收到对于的消息了

服务器发送 你好

同样的,网页端也收到了来自服务器的消息

那么这样,就完成了网页端的通信了

2.Winform

新建一个 winform 项目

先安装插件 SuperSocket.ClientEngine

再安装插件 WebSocket4Net

新建脚本 WSocketClient.cs

using SuperSocket.ClientEngine;
using System;
using System.Threading;
using System.Threading.Tasks;
using WebSocket4Net;namespace WebSocketClient
{public class WSocketClient : IDisposable{//收到消息后的回调//public event Action<string> MessageReceived;public Action<string> MessageReceived;private WebSocket4Net.WebSocket _webSocket;/// <summary>/// 检查重连线程/// </summary>Thread _thread;bool _isRunning = false;/// <summary>/// 是否在运行中/// </summary>public bool IsRunning => _isRunning;/// <summary>/// WebSocket连接地址/// </summary>public string ServerPath { get; set; }public WSocketClient(string url){ServerPath = url;this._webSocket = new WebSocket4Net.WebSocket(url);this._webSocket.Opened += WebSocket_Opened;this._webSocket.Error += WebSocket_Error;this._webSocket.Closed += WebSocket_Closed;this._webSocket.MessageReceived += WebSocket_MessageReceived;}/// <summary>/// 连接方法/// <returns></returns>public bool Start(){bool result = true;try{this._webSocket.Open();this._isRunning = true;this._thread = new Thread(new ThreadStart(CheckConnection));this._thread.Start();}catch (Exception ex){Console.WriteLine(ex.ToString());result = false;this._isRunning = false;}return result;}/// <summary>/// 消息收到事件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void WebSocket_MessageReceived(object sender, MessageReceivedEventArgs e){Console.WriteLine("Received:" + e.Message);if (MessageReceived != null)MessageReceived(e.Message);}/// <summary>/// Socket关闭事件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void WebSocket_Closed(object sender, EventArgs e){Console.WriteLine("websocket_Closed");}/// <summary>/// Socket报错事件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void WebSocket_Error(object sender, ErrorEventArgs e){Console.WriteLine("websocket_Error:" + e.Exception.ToString());}/// <summary>/// Socket打开事件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void WebSocket_Opened(object sender, EventArgs e){Console.WriteLine("websocket_Opened");}/// <summary>/// 检查重连线程/// </summary>private void CheckConnection(){do{try{if (this._webSocket.State != WebSocket4Net.WebSocketState.Open && this._webSocket.State != WebSocket4Net.WebSocketState.Connecting){Console.WriteLine("Reconnect websocket WebSocketState:" + this._webSocket.State);this._webSocket.Close();this._webSocket.Open();Console.WriteLine("正在重连");}}catch (Exception ex){Console.WriteLine(ex.ToString());}System.Threading.Thread.Sleep(5000);} while (this._isRunning);}/// <summary>/// 发送消息/// </summary>/// <param name="Message"></param>public void SendMessage(string Message){Task.Factory.StartNew(() =>{if (_webSocket != null && _webSocket.State == WebSocket4Net.WebSocketState.Open){this._webSocket.Send(Message);}});}public void Dispose(){try{_thread?.Abort();}catch (Exception ex){Console.WriteLine(ex.Message);}this._webSocket.Close();this._webSocket.Dispose();this._webSocket = null;this._isRunning = false;}}
}

winfrom 界面如下

Form1.cs

using System;
using System.Windows.Forms;
using WebSocketClient;namespace WinFormWebsocket
{public partial class Form1 : Form{private static string url = "ws://127.0.0.1:30000";private WSocketClient client = new WSocketClient(url);public Form1(){InitializeComponent();}private void Form1_Load(object sender, EventArgs e){Control.CheckForIllegalCrossThreadCalls = false;txtServerIP.Text = url;client.MessageReceived = MessageReceived;this.Text = "客户端";}private void Form1_FormClosing(object sender, FormClosingEventArgs e){if(client.IsRunning)client.Dispose();}/// <summary>/// 连接服务器/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnConnect_Click(object sender, EventArgs e){try{if(client.IsRunning){AddOrdinaryLog("已经连接服务器,不能重复执行");return;}bool result = client.Start();AddOrdinaryLog("连接是否成功:" + result);}catch (Exception ex){string err = string.Format("连接失败:{0}", ex.Message);Console.WriteLine(err);throw;}}/// <summary>/// 关闭服务器/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnClose_Click(object sender, EventArgs e){if (!client.IsRunning){AddOrdinaryLog("服务器未连接");return;}// 记得释放资源否则会造成堆栈client.Dispose();AddOrdinaryLog("连接已关闭");}/// <summary>/// 发送消息/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnSendMsg_Click(object sender, EventArgs e){string inputMsg = txtInputMsg.Text;if (string.IsNullOrEmpty(inputMsg)){MessageBox.Show("输入框不能为空");return;}client.SendMessage(inputMsg);AddOrdinaryLog(inputMsg);txtInputMsg.Text = string.Empty;}/// <summary>/// 服务端返回的消息/// </summary>private void MessageReceived(string msg){AddOrdinaryLog(msg);}/// <summary>/// 添加日志/// </summary>/// <param name="content"></param>private void AddOrdinaryLog(string content){//读取当前ListBox列表长度int len = ListBox_OrdinaryLogList.Items.Count;//插入新的一行ListBox_OrdinaryLogList.Items.Insert(len, content);//列表长度大于30,那么就删除第1行的数据if (len > 30)ListBox_OrdinaryLogList.Items.RemoveAt(0);//插入新的数据后,将滚动条移动到最下面int visibleItems = ListBox_OrdinaryLogList.ClientSize.Height / ListBox_OrdinaryLogList.ItemHeight;ListBox_OrdinaryLogList.TopIndex = Math.Max(ListBox_OrdinaryLogList.Items.Count - visibleItems + 1, 0);}}
}

到这里,所有的准备工作都做完了,下面就来测试一下效果吧。

首先,运行 WebSocket 服务器端,再运行客户端,点击连接按钮

服务器端也显示有客户端连接上了。

那么现在用客户端发送消息,输入恭喜发财,然后点击 发送消息 按钮,这时历史消息列表就有对于的记录。

这时,服务器端也同样的收到了来自客户端的消息。

接下来,我们用服务器向客户端发送消息,在控制台输入文字后,按回车,会自动发送

客户端收到了来自服务器的消息

这样,就完成了通讯部分的基本功能了。

源码:点击下载

结束

如果这个帖子对你有用,欢迎 关注 + 点赞 + 留言,谢谢

end

C# WebSocket(Fleck) 客户端:html Winfrom相关推荐

  1. 未能分析从服务器收到的消息,WebSocket Javascript客户端未收到来自服务器的消息...

    我已经在本地GlassFish 4.1服务器上部署了Java Web应用程序,该服务器实现了与Web客户端互操作的WebSockets.我能够通过套接字成功执行客户端到服务器的通信,但由于某种原因,服 ...

  2. WebSocket安卓客户端实现详解(一)–连接建立与重连

    http://blog.csdn.net/zly921112/article/details/72973054 前言 这里特别说明下因为WebSocket服务端是公司线上项目所以这里url和具体协议我 ...

  3. springboot2.0 + websocket + android客户端实战

    简介 WebSocket是HTML5中的协议,支持持久连接,可以有效解决客户端和服务端之间数据数据同步时需要轮询的问题. 效果图 服务端 创建web工程(此处省略) 引入websocket maven ...

  4. javaweb + websocket实现客户端 保存到session

    javaweb + websocket实现客户端 最近需要完成一个javaweb项目,但是没有和数据库连接而是通过websocket通讯实现和服务器端数据交互.我搜了好多,网上大部分都是通过页面web ...

  5. fleck 客户端_C# Fleck的WebSocket使用

    (1). Web网页端代码 WebSocket测试 .div1 { height:88px; width:173px; border:1px solid blue; margin:auto; } h4 ...

  6. fleck 客户端_C#中使用Fleck实现WebSocket通信简例

    Fleck是一个开源的使用C#封装的WebSocket服务端工具库. 一.服务端搭建 这里选择在.net core 2.1框架下新建了一个控制台程序 在项目里使用NuGet引入Fleck包 NuGet ...

  7. fleck 客户端_关于C#使用Fleck 的websocket问题

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 先上代码: FleckLog.Level = LogLevel.Debug; allSockets = new List(); Newsocket = n ...

  8. 日志读取_php作为websocket的客户端实时读取推送日志文件

    首先要使用composer来下载一个第三方扩展就可以实现php的websocket客户端,直接在当前目录生成下composer.json文件就可以了. composer require textalk ...

  9. websocket多客户端接收消息_WebSocket之消息接收发送

    WebSocket协议是基于TCP的一种新的网络协议.它实现了浏览器与服务器全双工(full-duplex)通信--允许服务器主动发送信息给客户端. 在 WebSocket API 中,浏览器和服务器 ...

最新文章

  1. linux如何右键新建文件夹,在Ubuntu 18.04右键菜单中增加新文档(New Document)及其他类型选项...
  2. pdf在浏览器的显示问题
  3. 函数不可以直接调用其他函数内部定义的变量_python的函数
  4. 后台定时统计任务太耗时如何优化一下
  5. 【实践】短视频场景下信息流广告的挑战和技术实践.pdf(附下载链接)
  6. mysql 事务 注意 优化_MySQL入门详解(二)---mysql事务、锁、以及优化
  7. ASP.NET网站限制访问频率
  8. 移动端页面制作字号大小设定问题,设计稿文字字号规范,解决移动端大小屏适配问题
  9. PHP获取表单数据的方法有几种,php获取表单数据的两种方法说明
  10. 超30亿人脸数据被泄露,美国AI公司遭科技巨头联合“封杀”
  11. 密探查询系统服务器码,车辆国几排放查询
  12. 计算机在语文教学中,计算机技术在语文教学中的运用
  13. 导出带有表格的word文件时,换页自带表头,避免复杂的表格数行数计算
  14. SQL中存储过程和函数的标准写法
  15. 样本总体方差有偏估计和无偏估计的理解
  16. 【python】通过信号机制对子进程进行控制
  17. 对称数(自己的算法)
  18. 微信转发的文件服务器留存吗,微信转发这种视频会感染病毒泄露隐私?网警的查证结果来了...
  19. char*data和char data[]
  20. 2022 届大四学长实习心得、职场经验分享、转型思考

热门文章

  1. 傅里叶变换的一些总结
  2. 关联分析(Association Analysis)--挖掘啤酒与尿布的关联规则
  3. 【荧光光谱】用matlab绘制荧光光谱图
  4. Redis(二) -- redis.conf详解(redis6)
  5. GdPicture.NET SDK Crack,提供多种打印功能
  6. IDA pro与x64dbg地址对齐
  7. 获取字符串中最大的数字
  8. 大数据到底应该如何学?
  9. Android 65536错误:Cannot fit requested classes in a single dex file
  10. easyUI中combobox中idFeild和textFeild的取值方法