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

发布时间:2024年01月03日

场景

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;
??????? }

文章来源:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/135367154
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。