Winform中使用Fleck实现Websocket服务端并读取SQLite数据库中数据定时循环群发消息

场景

Winform中使用Websocket4Net实现Websocket客户端并定时存储接收数据到SQLite中:

Winform中使用Websocket4Net实现Websocket客户端并定时存储接收数据到SQLite中-CSDN博客

Winform中操作Sqlite数据增删改查、程序启动时执行创建表初始化操作:

Winform中操作Sqlite数据增删改查、程序启动时执行创建表初始化操作_winform sqllite-CSDN博客

在上面实现Websocket客户端的基础上,如何实现Websocket服务端,并实现定时给所有的客户端群发消息。

群发的消息从SQLite中读取,循环进行群发。

注:

博客:
霸道流氓气质_C#,架构之路,SpringBoot-CSDN博客

实现

1、Fleck

GitHub - statianzo/Fleck: C# Websocket Implementation

新建Winform项目,并使用Nuget引入依赖

搜索Fleck

按照官网说明,快速实现Websocket服务端只需要

var server = new WebSocketServer("ws://0.0.0.0:8181");
server.Start(socket =>
{socket.OnOpen = () => Console.WriteLine("Open!");socket.OnClose = () => Console.WriteLine("Close!");socket.OnMessage = message => socket.Send(message);
});

并且官方提供了一些示例demo,比如群发消息的实现,这里是在控制台项目中的示例

            var allSockets = new List<IWebSocketConnection>();var server = new WebSocketServer("ws://0.0.0.0:8181");server.Start(socket =>{socket.OnOpen = () =>{Console.WriteLine("Open!");allSockets.Add(socket);};socket.OnClose = () =>{Console.WriteLine("Close!");allSockets.Remove(socket);};socket.OnMessage = message =>{Console.WriteLine(message);allSockets.ToList().ForEach(s => s.Send("Echo: " + message));};});

demo位置

2、这里基于Winform设计窗体布局如下

3、启动服务端/开始监听按钮点击事件

新建WebSocketServer服务端对象,便于停止监听

public WebSocketServer wsServer= null;

新建一个list用来存储所有的客户端连接信息

private List<IWebSocketConnection> allSockets = new List<IWebSocketConnection>();

然后在开始监听按钮的点击事件中

        private void button_start_listen_Click(object sender, EventArgs e){try{allSockets.Clear();string wsAddress = textBox_server_address.Text.Trim();wsServer = new WebSocketServer(wsAddress);    //创建webscoket服务端实例wsServer.Start(socket => {socket.OnOpen = () =>{//Console.WriteLine("Open");allSockets.Add(socket);};socket.OnClose = () =>{//Console.WriteLine("Close");allSockets.Remove(socket);};socket.OnMessage = message => {//Console.WriteLine(message);                  };socket.OnError = message =>{//Console.WriteLine(message);};});textBox_log.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":监听成功");textBox_log.AppendText("\r\n");}catch (Exception exception){textBox_log.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":监听异常:" + exception.Message);textBox_log.AppendText("\r\n");}         }

在建立连接和关闭事件中分别对客户端的list进行添加和删除。

4、停止监听的按钮点击事件中

遍历所有客户端的list,循环进行关闭,并销毁服务端对象

        private void button_stop_listen_Click(object sender, EventArgs e){allSockets.ToList().ForEach(s => s.Close());wsServer.Dispose();textBox_log.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":监听停止");textBox_log.AppendText("\r\n");}

5、单次群发按钮点击事件

        private void button_single_mass_Click(object sender, EventArgs e){if (null != wsServer){string message = textBox_message.Text.Trim();allSockets.ToList().ForEach(s => {if (s.IsAvailable){s.Send(message);}});}else {textBox_log.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":wsServer未启动");textBox_log.AppendText("\r\n");}}

判断服务端对象不为空,遍历所有客户端list,判断如果可用则调用send方法,发送string类型的消息。

6、加载数据按钮实现

用来从SQLite中读取需要循环群发的消息内容

首先声明string的list用来存储加载的数据

private List<string> loadDataList = new List<string>();

然后按钮的点击事件中

        private void button_load_data_Click(object sender, EventArgs e){try{if (null == wsServer){textBox_log.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":wsServer未启动");textBox_log.AppendText("\r\n");}else{loadDataList.Clear();SQLiteDataReader reader = Global.Instance.sqlLiteHelper.ExecuteQuery("SELECT* FROM positions;");if (reader.HasRows){while (reader.Read()){string data = reader.GetString(reader.GetOrdinal("data"));loadDataList.Add(data);}}textBox_log.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":加载数据完成,共("+ loadDataList.Count+")条。");textBox_log.AppendText("\r\n");}}catch (Exception exception){textBox_log.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":加载数据异常:" + exception.Message);textBox_log.AppendText("\r\n");}}

7、定时群发实现

首先新建定时器以及加载的数据的索引

Timer _timerMass = new Timer();private int index = 0;

定时群发按钮点击事件实现

        private void button_start_mass_Click(object sender, EventArgs e){if (null == wsServer) {textBox_log.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":wsServer未启动");textBox_log.AppendText("\r\n");} else {_timerMass.Interval = (int)numericUpDown_mass.Value;_timerMass.Tick += _timer_Tick_Mass;_timerMass.Start();textBox_log.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":定时群发已经启动!!");textBox_log.AppendText("\r\n");}}

定时器执行方法具体实现

        private void _timer_Tick_Mass(object sender, EventArgs e){if (loadDataList.Count>0) {if (index > loadDataList.Count - 1){index = 0;}string data = loadDataList[index];allSockets.ToList().ForEach(s => {if (s.IsAvailable) {s.Send(data);}             });index++;}}

8、停止定时群发按钮点击事件实现

        private void button_stop_mass_Click(object sender, EventArgs e){//停止定时器_timerMass.Tick -= _timer_Tick_Mass;_timerMass.Stop();textBox_log.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":定时群发已经停止!!!");textBox_log.AppendText("\r\n");index = 0;}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/594304.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue3 结合typescript 组合式函数(2)

安装axios&#xff1a;npm install axios 1、hooks文件夹下新建useURLLoader 在APP.VUE中使用useURLLoader 使用Dog API 2、使用对象中的属性&#xff0c;必须使用toRefs&#xff0c;否则Reactive响应失效 3、使用泛型 结果&#xff1a;

C++不懂就问:std::vector的push_back和emplace_back函数的差别?

欢迎关注公众号(20YC编程)&#xff0c;视频号也有免费视频课程哦&#xff01; -今日内容- 1 emplace_back介绍 std::vector的emplace_back&#xff08;包括emplace&#xff09;函数是C11引入的新特性&#xff0c;用于在容器中直接构造元素&#xff0c;而不是先构造元素再插入…

3 - 字段约束|MySQL索引|MySQL用户管理

字段约束&#xff5c;MySQL索引&#xff5c;MySQL用户管理 字段约束主键外键 MySQL索引索引介绍优缺点索引使用规则索引的分类索引的管理 用户管理用户授权权限撤销 用户权限追加user表的使用 字段约束 设置在表头上&#xff0c;用来限制字段赋值 包括&#xff1a; 是否允许给…

基于深度学习的交通标志图像分类识别系统

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长 QQ 名片 :) 1. 项目简介 本文详细探讨了一基于深度学习的交通标志图像识别系统。采用TensorFlow和Keras框架&#xff0c;利用卷积神经网络&#xff08;CNN&#xff09;进行模型训练和预测&#xff0c;并引入VGG16迁移学习…

MySQL基础学习: 由delete和insert操作导致的死锁问题

一、问题复现&#xff1a;表结构 CREATE TABLE user_props (user_id bigint NOT NULL ,prop_key varchar(100) NOT NULL ,prop_value varchar(100) NOT NULL,PRIMARY KEY (user_id,prop_key) )二、死锁测试 &#xff08;1&#xff09;开启两个事务 &#xff08;2&#xff09;…

QGIS设计导出Geoserver服务使用的SLD样式

1、打开QGis软件 2、打开shp文件所在所在文件夹&#xff0c;双击添加选中图层 3、编辑shp文件样式 &#xff08;1&#xff09;双击“Layers”中需要编辑的图层 &#xff08;2&#xff09;选择样式 &#xff08;3&#xff09;编辑样式后&#xff0c;选择“应用”—》“确定” 4…

安装MYsql5.7和8.0以及区别

MySQL5.7的安装步骤 解压 将my.ini文件拷贝到解压的目录下 更改my.ini文件&#xff0c;将安装目录替换&#xff0c;并将\改成\\ 在bin目录下进入cmd 执行安装&#xff1a; mysqld install 失败可能是应为没有用管理员身份执行cmd&#xff0c;要在开始菜单进入cmd &#xff…

【致远FAQ】V8.0sp1_门户设置——页面组件中设置列表头的颜色

问题描述 门户设置——页面组件中设置列表头的颜色后&#xff0c;底表数据查看时的列表头颜色没有变呢 解决办法 设置不对cap4生效&#xff0c;只针对原始oa的列表支持&#xff08;比如协同工作——已办事项、公文等列表项&#xff09; 设置参考

深度学习|2.4 梯度下降

如上图&#xff0c; J ( w , b ) J(w,b) J(w,b)是由w和b两个参数共同控制的损失函数&#xff0c;损失是不好的东西&#xff0c;所以应该求取合适的w和b使得损失最小化。 为了简单考虑&#xff0c;可以先忽略参数b。 斜率可以理解成在朝着x正方向移动单位距离所形成的损失值的变…

解读 $mash 通证 “Fair Launch” 规则,将公平发挥极致

Solmash 是 Solana 生态中由社区主导的铭文资产 LaunchPad 平台&#xff0c;该平台旨在为 Solana 原生铭文项目&#xff0c;以及通过其合作伙伴 SoBit 跨链桥桥接到 Solana 的 Bitcoin 生态铭文项目提供更广泛的启动机会。有了 Solmash&#xff0c;将会有更多的 Solana 生态的铭…

如何跨系统构建docker镜像?

转载说明&#xff1a;如果您喜欢这篇文章并打算转载它&#xff0c;请私信作者取得授权。感谢您喜爱本文&#xff0c;请文明转载&#xff0c;谢谢。 1. 前言 docker镜像有基于amd64系统的&#xff0c;也有基于arm64系统的。 前段时间用了一个在x86_64的centos7服务器上构建的i…

NSSCTF sql

开启环境: ?wllm1 回显正常,试试?wllm1 出现报错;加上%23正常 ?wllm-1or 11%23出现过滤 测试,空格用**替代, 等号用like替代 测试长度 ?wlmm1order/**/by/**/3%23正常 ?wlmm1order/**/by/**/4%23报错 长度为3,测试回显位置: ?wlmm-1union/**/select/**/1,2,3%23 …

快速入门ESP32——点亮你的第一个LCD屏幕

相关文章 快速入门ESP32——开发环境配置Arduino IDE 快速入门ESP32——开发环境配置PlatformIO IDE 快速入门ESP32—— platformIO添加开源库和自己的开发库 快速入门ESP32—— 解决platformIO添加开源库下载失败的问题 快速入门ESP32——点亮你的第一个LCD屏幕 前言一、移植T…

B01、运行时数据区概述-03

1、什么是内存 内存是非常重要的系统资源,是硬盘和CPU的中间仓库及桥梁,承载着操作系统和应用程序的实时运行。JVM内存布局规定了Java在运行过程中内存申请、分配、管理的策略,保证了JVM的高效稳定运行。不同的JVM对于内存的划分方式和管理机制存在着部分差异。 2、线程共享和…

利用MATLAB绘制折线图

x20:20:140;%x轴上的数据&#xff0c;第一个值代表数据开始&#xff0c;第二个值代表间隔&#xff0c;第三个值代表终止a[0.85, 2.2, 3.45, 2.65, 1.5, 1.9, 1.25]; %a数据y值plot(x,a,-*b); %线性&#xff0c;颜色&#xff0c;标记 axis([0,160,0,4]) %确定x轴与y轴框图大小 …

WIN10自带查看硬盘运行时间的指令

#创作灵感# 之前一直在捣腾电脑&#xff0c;最近又搞了个R720XD&#xff08;后续会有分享&#xff09;&#xff0c;所以对硬盘比较关注&#xff0c;查了一下硬盘方面的一些坑&#xff0c;机械硬盘最关注的问题就是运行时间了。 #正文# 查看硬盘运行时间需要用到Get-Disk指令&a…

电脑提示找不到msvcp140.dll的修复方法,亲测有效的两种方法

msvcp140.dll是Microsoft Visual C 2015 Redistributable的一个组件&#xff0c;它包含了许多C运行时库文件。这些库文件为运行基于C编写的应用程序提供了必要的支持。当系统中缺少某个或某些库文件时&#xff0c;就可能出现msvcp140.dll丢失的错误。 一、以下是msvcp140.dll文…

【数据结构】二叉树(一)——树和二叉树的概念及结构

前言: 本篇博客主要了解什么是树&#xff0c;什么是二叉树&#xff0c;以及他们的概念和结构。 文章目录 一、树的概念及结构1.1 树的基本概念1.2 树的相关特征1.3 树的实现 二、二叉树的概念及性质2.1 二叉树的概念2.2 二叉树的性质 一、树的概念及结构 1.1 树的基本概念 树&…

Multisim仿真实例(1-10)

本文分享10个常用电路&#xff0c;供大家参考学习&#xff0c;需要具体资料可以私聊我。 1、基于三极管的DC-AC全桥逆变电路 该电路利用脉冲控制Q1/Q3与Q2/Q4导通从而改变电流流过负载的方向&#xff0c;将直流信号逆变成交流信号。 电路图&#xff1a; 输入输出结果&#x…

springboot整合webservice使用总结

因为做的项目中用到了webservice,所以在此总结一下。 一、webservice简介 Web Service也叫XML Web Service, WebService是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求&#xff0c;轻量级的独立的通讯技术。是通过SOAP在Web上提供的软件服务&#xff0c;使…