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

场景

SpringBoot+Vue整合WebSocket实现前后端消息推送:

SpringBoot+Vue整合WebSocket实现前后端消息推送_websocket vue3.0 springboot 往客户端推送-CSDN博客

上面实现ws推送数据流程后,需要在windows上使用ws客户端定时记录收到的数据到文件中,这里

文件使用SQLite数据库进行存储。

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

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

Sqlite的操作参考如上。

注:

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

实现

1、引入WebSocket4Net依赖

使用Nuget搜索并安装WebSocket4Net

2、设计页面布局如下

3、websocket客户端实现

声明客户端对象

复制代码
public static WebSocket4Net.WebSocket webSocket4NetClient = null;

ws连接按钮的点击事件中

复制代码
            try {
                var wsAddresss = textBox_ws_address.Text.Trim();
                webSocket4NetClient = new WebSocket4Net.WebSocket(wsAddresss);
                webSocket4NetClient.Opened += WebSocket4Net_Opened;
                webSocket4NetClient.Error += Websocket_Error;
                webSocket4NetClient.Closed += new EventHandler(Websocket_Closed);
                webSocket4NetClient.MessageReceived += WebSocket4Net_MessageReceived;
                webSocket4NetClient.Open();
                textBox_log.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":ws开始连接");
                textBox_log.AppendText("\r\n");
            } catch (Exception exception) {
                textBox_log.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":ws连接异常:"+ exception.Message);
                textBox_log.AppendText("\r\n");
            }

这里未添加对ws地址的校验,只关注中间ws相关的代码

复制代码
                webSocket4NetClient = new WebSocket4Net.WebSocket(wsAddresss);
                webSocket4NetClient.Opened += WebSocket4Net_Opened;
                webSocket4NetClient.Error += Websocket_Error;
                webSocket4NetClient.Closed += new EventHandler(Websocket_Closed);
                webSocket4NetClient.MessageReceived += WebSocket4Net_MessageReceived;
                webSocket4NetClient.Open();

然后编写其各种事件的具体实现。

实现方法中具体逻辑根据业务进行确定。

建立连接事件实现

复制代码
        private void WebSocket4Net_Opened(object sender, EventArgs e)
        {
            //允许跨线程调用
            Control.CheckForIllegalCrossThreadCalls = false;
            textBox_log.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":ws建立连接成功");
            textBox_log.AppendText("\r\n");
            //向服务端发送消息
            //webSocket4NetClient.Send("Client准备发送数据!");
        }

收到消息事件实现

复制代码
        private void WebSocket4Net_MessageReceived(object sender, MessageReceivedEventArgs e)
        {
            //允许跨线程调用
            Control.CheckForIllegalCrossThreadCalls = false;
            //textBox_log.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":收到消息:");
            //textBox_log.AppendText("\r\n");
            receviceString = e.Message;
        }

出错事件实现

复制代码
        private void Websocket_Error(object sender, EventArgs e)
        {
            //允许跨线程调用
            Control.CheckForIllegalCrossThreadCalls = false;
            textBox_log.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":Websocket_Error:"+e);
            textBox_log.AppendText("\r\n");
        }

连接关闭事件实现

复制代码
        private void Websocket_Closed(object sender, EventArgs e)
        {
            //允许跨线程调用
            Control.CheckForIllegalCrossThreadCalls = false;
            textBox_log.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":Websocket_Closed");
            textBox_log.AppendText("\r\n");
        }

ws连接关闭按钮点击实现

复制代码
        private void button_ws_disconnec_Click(object sender, EventArgs e)
        {
            webSocket4NetClient.Close();
        }

4、定时存储实现

在上面收到消息时将数据赋值给变量

receviceString

声明变量

复制代码
private string receviceString = String.Empty;

添加Timer定时器

复制代码
Timer _timer = new Timer();

定时存储按钮点击事件实现

复制代码
        private void button_start_store_Click(object sender, EventArgs e)
        {
            if (webSocket4NetClient.State != WebSocket4Net.WebSocketState.Open && webSocket4NetClient.State != WebSocket4Net.WebSocketState.Connecting)
            {
                textBox_log.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":Websocket连接异常");
                textBox_log.AppendText("\r\n");
            }
            else {
                //清空数据库
                SQLiteDataReader reader = Global.Instance.sqlLiteHelper.ExecuteQuery("SELECT* FROM positions;");
                if (reader.HasRows)
                {
                    while (reader.Read())
                    {
                        Global.Instance.sqlLiteHelper.ExecuteQuery("DELETE FROM positions WHERE timestamp = " + reader.GetString(reader.GetOrdinal("timestamp")) + ";");
                    }
                }
                _timer.Interval = (int)numericUpDown_rate.Value;
                _timer.Tick += _timer_Tick;
                _timer.Start();
                textBox_log.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":定时存储已经启动!!");
                textBox_log.AppendText("\r\n");
            }
        }

首先判断ws是否连接上,如果连接上则将库清空,然后获取设置的定时频率并启动定时器

定时器具体实现

复制代码
        private void _timer_Tick(object sender, EventArgs e) {
            try
            {
                if (webSocket4NetClient.State != WebSocket4Net.WebSocketState.Open && webSocket4NetClient.State != WebSocket4Net.WebSocketState.Connecting)
                {
                    textBox_log.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":Websocket连接异常");
                    textBox_log.AppendText("\r\n");
                }
                else {
                    if (!String.IsNullOrEmpty(receviceString))
                    {
                        //获取ws数据并存储进数据库
                        TimeSpan ts = DateTime.Now.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
                        string timeSpan = Convert.ToInt64(ts.TotalSeconds).ToString();
                        //插入数据
                        Global.Instance.sqlLiteHelper.InsertValues("positions", new string[] { timeSpan, receviceString });
                        receviceString = String.Empty;
                    }
                }
            }
            catch (Exception exception)
            {
                textBox_log.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":定时存储执行异常:" + exception.Message);
                textBox_log.AppendText("\r\n");
            }        
        }

首页也要判断是否连接,然后判断receviceString是否为空,避免ws未传输数据,会定时存储空数据。

不为空则将时间和收到的数据存储进数据库。

停止定时存储按钮点击事件

复制代码
        private void button_stop_store_Click(object sender, EventArgs e)
        {
            //停止定时器
            _timer.Tick -= _timer_Tick;
            _timer.Stop();
            textBox_log.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + ":定时存储已经停止!!!");
            textBox_log.AppendText("\r\n");
            receviceString = String.Empty;
        }

5、运行效果

相关推荐
Moyu_Friday15 小时前
网络安全基础-计算机网络应用与协议
网络协议·计算机网络
徐同保1 天前
免费ssl证书全流程AI配置(含七牛云cdn)
网络·网络协议·ssl
幻智星科技1 天前
一个开源的纯FPGA网口采集卡
网络协议·fpga开发·udp
anew___1 天前
《从零手写操作系统 (48):网络协议栈基础——Socket API与TCP/IP分层架构》
网络协议·tcp/ip·架构
TMT星球1 天前
2026阅文创作大会:首批AI精品动画亮相,推出OPC一站式平台与IP委员会模式
人工智能·网络协议·tcp/ip
weixin_382395231 天前
0-500 人工厂的生产 PMC 系统怎么做?基于 Tauri + SQLite 的性能架构实践与 5000 物料压测实录
数据库·架构·sqlite
程序员夏洛1 天前
TCP 和 UDP 有什么区别?
网络协议·tcp/ip·udp
跨境数据猎手1 天前
机房、住宅、原生IP区别在哪,三类代理的说明
网络·网络协议·tcp/ip
winfredzhang1 天前
从零实现“照片按地理位置显示在矢量地图上”:Flask + SQLite + Leaflet 全栈实战
python·sqlite·flask