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

news2024/11/14 18:41:14

场景

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、运行效果

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

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

相关文章

鸿蒙开发学习——基本组件

文章目录 引言正文Image组件设置加载网络图片图片属性设置 Text组件设置文本显示内容text属性设置 TextInput输入文本TextInput Controller获取输入文本 Button按钮 引言 最近在学习鸿蒙系统开发,然后对着文档看还是有很多问题,这里结合官方给的demo进行…

在ARMv8中aarch64与aarch32切换

需求描述 在项目调试过程中,由于内存或磁盘空间不足需要将系统从aarch64切换到aarch32的运行状态去执行,接下来记录cortexA53的调试过程。 相关寄存器描述 ARM64: SPSR_EL3 N (Negative):表示运算结果的最高位,用于指示运算结果是否为负数。 Z (Zero):表示运算结果是否…

设计模式之建造者模式【创造者模式】

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档> 学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰。各位小伙伴,如果您: 想系统/深入学习某…

c++语言基础17-判断集合成员

题目描述 请你编写一个程序&#xff0c;判断给定的整数 n 是否存在于给定的集合中。 输入描述 有多组测试数据&#xff0c;第一行有一个整数 k&#xff0c;代表有 k 组测试数据。 每组数据第一行首先是一个正整数 m&#xff0c;表示集合中元素的数量&#xff08;1 < m &…

程序媛的mac修炼手册--MacOS系统更新升级史

啊&#xff0c;我这个口罩三年从未感染过新冠的天选免疫王&#xff0c;却被支原体击倒&#x1f637;大意了&#xff0c;前几天去医院体检&#xff0c;刚检查完出医院就摘口罩了&#x1f926;大伙儿还是要注意戴口罩&#xff0c;保重身体啊&#xff01;身体欠恙&#xff0c;就闲…

微软截图工具SnippingTool_6.1.7601免费版

SnippingTool是一款win7系统自带的一款非常实用型截图工具&#xff0c;操作简单&#xff0c;点击“新建"可一键截图&#xff0c;截图之后会弹出编辑器&#xff0c;可以进行一些简单的勾画编辑操作&#xff0c;您可以使用笔、荧光笔、电子邮件或保存等选项。如果您的系统丢…

Liunx(CentOS)安装Nacos(单机启动,绑定Mysql)

Liunx安装Nacos(单机启动&#xff0c;绑定Mysql) 一&#xff0c;准备安装包 github下载点 二&#xff0c;在/usr/local/目录下创建一个文件夹用于上传和解压Nacos cd /usr/local/ #这里创建文件夹名字可随意&#xff0c;解压后会生成一个名为nacos的文件夹&#xff0c;后续…

全国计算机等级考试| 二级Python | 真题及解析(6)

全国计算机等级考试二级Python真题及解析(8)图文 一、选择题 1.python中表达式4**3=( )。 A.12 B.1 C.64 D.7 2.在Python中,通过( )函数查看字符的编码。 …

安全防御之授权和访问控制技术

授权和访问控制技术是安全防御中的重要组成部分&#xff0c;主要用于管理和限制对系统资源&#xff08;如数据、应用程序等&#xff09;的访问。授权控制用户可访问和操作的系统资源&#xff0c;而访问控制技术则负责在授权的基础上&#xff0c;确保只有经过授权的用户才能访问…

jQuery框架

1.1、jQuery简介 jQuery 是一个高效、精简并且功能丰富的 JavaScript 工具库。它提供的 API 易于使用且兼容众多浏览器&#xff0c;这让诸如 HTML 文档遍历和操作、事件处理、动画和 Ajax 操作更加简单。目前超过90%的网站都使用了jQuery库&#xff0c;jQuery的宗旨&#xff1…

ElecardStreamEye使用教程(视频质量分析工具、视频分析)

文章目录 Elecard StreamEye 使用教程安装与设置下载安装 界面导航主菜单视频窗口分析窗口 文件操作打开视频文件 视频流分析帧类型识别码率分析分析报告 高级功能视觉表示比较模式自动化脚本 下载地址1&#xff1a;https://www.onlinedown.net/soft/58792.htm 下载地址2&…

计算机系统基础

C 语言相关内容省略&#xff0c;复习自用&#xff0c;仅供参考~ 概述 冯诺伊曼结构 存储程序工作方式&#xff1a;将事先编好的程序和原始数据送入主存后才能执行程序&#xff0c;程序被启动执行后&#xff0c;计算机能在不需要操作人员干预下自动完成逐条指令取出和执行的任…

【电商项目实战】实现订单超时支付取消

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《电商项目实战》。&#x1f3af;&#x1f3af; &am…

OpenHarmony源码转换器—多线程特性转换

本文讨论了如何将多线程的 Java 代码转换为 OpenHarmony ArkTS 代码​ 一、简介 Java 内存共享模型 以下示例伪代码和示意图展示了如何使用内存共享模型解决生产者消费者问题。 生产者消费者与共享内存间交互示意图 为了避免不同生产者或消费者同时访问一块共享内存的容器时…

阶段十-分布式-Redis02

第一章 Redis 事务 1.1 节 数据库事务复习 数据库事务的四大特性 A&#xff1a;Atomic &#xff0c;原子性&#xff0c;将所以SQL作为原子工作单元执行&#xff0c;要么全部执行&#xff0c;要么全部不执行&#xff1b;C&#xff1a;Consistent&#xff0c;一致性&#xff0…

Vue前端文字效果:如何让一段文本像是手动一个一个字打出来的

效果展示 自己做的AI聊天机器人界面&#xff0c;我觉得比微信还好看 由于这个前端略微复杂&#xff0c;下文用最简单的例子来展示&#xff1a; 分析需求 对于AI聊天工具的前端&#xff0c;如果AI生成的文本像是一个一个字打出来的&#xff0c;就会让AI看起来更像真的人&…

详解卡尔曼滤波(Kalman Filter)

1. 从维纳滤波到卡尔曼滤波 黑盒&#xff08;Black Box&#xff09;思想最早由维纳&#xff08;Wiener&#xff09;在1939年提出&#xff0c;即假定我们对从数据到估计中间的映射过程一无所知&#xff0c;仅仅用线性估计&#xff08;我们知道在高斯背景下&#xff0c;线性估计…

STM32 HAL库定时器触发DMA并口数据传输

代码目的&#xff1a; STM32与FPGA通讯&#xff0c;通过8位并口线进行通讯&#xff0c;16byte的数据在10us之内通过8位并口数据线传给FPGA&#xff0c;FPGA读取该数据。 HAL库设置说明&#xff1a; 时钟采用80MHz&#xff0c;由于16byte的数据要在10us之内传完&#xff0c;那…

[笔记] 使用 qemu 创建虚拟磁盘并安装 grub

之前使用 wsl 进行了直接创建虚拟磁盘并安装 grub,现在希望能够直接借助 qemu 的工具创建虚拟磁盘文件并安装 grub,由于需要用到 nbd(net block device网络块设备) 模块,在 wsl 中并不支持,因此这里使用到了 Hypver-V 虚拟机创建了一个 Ubuntu 系统,在系统中安装了 qemu 和 gru…

物联网安全:保护关键网络免受数字攻击

物联网 (IoT) 彻底改变了当今互联世界中的各个行业&#xff0c;实现了智能家居、自动驾驶汽车和先进的工业系统。然而&#xff0c;随着物联网设备数量的急剧增加&#xff0c;这些设备和相应网络的安全性已成为人们关注的焦点。本文旨在探讨物联网安全的重要性&#xff0c;同时简…