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