ASP.net Web 表单应用程序中的实时数据:如何使用新传入数据更新(刷新)屏幕

Real Time Data in ASP.net Web Form App : How to update (refresh) screen with new incoming data

我知道有很多关于这个特定主题的问题,但我找不到适合我情况的问题。

我的测试应用程序是使用 ASP.Net Web 表单构建的。我使用的库是与 .Net Core 不兼容的 .Net 库,因此我仅限于 .net Framework。

我正在使用提供连接和数据处理的第三方库从 PLC 服务器(使用 TCP/IP 的 Modbus 协议)检索数据,处理程序...我不需要实施“模型”或“控制器”,因为一切都在 类 内处理。这是一个例子:

//References
 using AutomatedSolutions.Win.Comm;
 using MB = AutomatedSolutions.Win.Comm.MB.Master;
 using System;
 using System.Text;
 using System.Web.UI.WebControls;
protected void Page_Load(object sender, EventArgs e)
{
 //Properties Instantiation
  mbChannel = new MB.Net.Channel(); //Connection to the server TCP/IP
  device1 = new MB.Device(); //Device sending data (temp, speed, ...)
  group1 = new MB.Group(false, 500); //Abstract class with a "dataChanged event"

  item1 = new MB.Item(); //Represents a specific data point (tag)

  group1.Items.Add(item1);
  mbChannel.Devices.Add(device1);
  device1.Groups.Add(group1);

 //Data changed Event Handler
  item1.DataChanged += new Item.DataChangedEventHandler(Item_DataChanged);

 //Polling activation
  group1.Active = true;
}

连接到服务器后,“Item.DataChangedEventHandler”每 500 毫秒触发一次,可以从“项目”中检索新数据。

"Item.DataChangedEventHandler" 代码:

private void Item_DataChanged(object sender, EventArgs evArgs)
        {
            Item evItem = (Item)sender;
            TextBox1.Text = TextBox1.Text + DateTime.Now.ToString("hh:mm:ss:fff") + " Item.DataChange event fired, quality is " + evItem.Quality.ToString();
            if (evItem.Quality == AutomatedSolutions.Win.Comm.Quality.GOOD)
            {
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < evItem.Elements; i++)
                {
                    sb.Append(evItem.Values[i].ToString() + ",");
                }
                WriteResult(sb.ToString());
            }
        }

WriteResults代码:

        private void WriteResult(string result)
        {
            Result.Text = result;
        }

DoRead 代码:此函数由按钮动作触发,一次读取一项。这工作正常,读取值显示在“文本框”

        private void DoRead(TextBox tb)
        {
            Result result;
            try
            {
                device1.Read(item1, out result);
                if (result.IsOK)
                {
                    StringBuilder sb = new StringBuilder();
                    for (int i = 0; i < item1.Elements; i++)
                    {
                        sb.Append(item1.Values[i].ToString() + ",");
                        sb.Length = sb.Length - 1;
                        tb.Text = sb.ToString();
                        TextBox1.Text = "Success";
                    }
                }
                else
                {
                    TextBox1.Text = TextBox1.Text + result.EvArgs.Message;
                }
            }
            catch (Exception ex)
            {
                TextBox1.Text = TextBox1.Text + ex.Message;
            }
        }

我的问题是,虽然使用“DoRead”方法读取项目的值工作正常,但未显示从“dataChanged”事件收集的数据。未触发 TextChanged 事件。

如何使用传入数据更新页面?

嗯,如上所述,您需要掌握 Web 表单或页面的生命周期。

后面的代码只存在于我们所说的往返过程中。

于是,用户请求了一个网页。页面 class 和变量等已创建。 运行s后面的代码,页面发送到客户端。

然后服务器端页面被丢弃 - 不再存在 (现在一遍又一遍地阅读它!!-服务器端代码、变量和页面被丢弃了-它不存在!!!)。

你必须毫无疑问地掌握以上概念。

所以,网页现在被发送到客户端,浏览器重新绘制该页面。它只是坐在用户桌面上,服务器页面 code/page/variable 等现在已经消失了!!!!

最终用户可以拔下他们计算机的插头,也许可以走捷径并转到 google.com。该页面已与网络服务器断开连接!

它从未连接过。该网页就位于用户桌面上。背后的代码早已消失 - 不再存在!!!

Web 服务器因此就坐在那里。它正在等待任何用户的 post-返回。它不会在内存中保存或保留您的网页和代码的副本。 Web 服务器可以接受任何网页请求。

因此,您不能在此过程中运行在网页中保留某些代码。

如果桌面上有网页的 10 个用户中有任何一个点击了按钮?然后,如果发生 post-back,则整个网页将发送到等待该请求的一个 Web 服务器。

然后重新加载页面。页面 class 和变量被重新初始化(从头开始)。现在后面的代码 运行s。您可以更改网页上的内容,只有当所有代码都完成后 运行ning 才会将页面发送回浏览器,然后浏览器会再次重新加载整个页面。

我的意思是,如果该页面有 10 个用户 post 会怎样?您现在拥有该代码和页面的 10 个副本 运行ning!!!!哪个将连接到外部进程??

你有这个设置:

注意页面是如何位于客户端的。在服务器上,没有该页面的实例 class。 (再读一遍这句话!!!)

注意这里非常小心 - 网页在客户端计算机上 - 它根本不存在于网络服务器端。

你没有这个:

你也没有这个:

上面是用户桌面上的网页,然后是服务器上的网页。

你没有那个设置。

页面服务器端不存在。

所以,你有一个网页,你点击了一个按钮:

好的,您点击按钮。现在开始所谓的往返。

所以你点击一个按钮整个网页就是 发送到服务器。你现在有这个:

现在在上面,我想图表可以显示网页也仍然是客户端。但是我把它漏掉了。

现在页面 class 的一个实例已创建,您的后台代码开始 运行ning。

您的隐藏代码可以修改控件(甚至可见),但页面不与用户交互 - 只有代码可以修改网页。

然后将网页发送回客户端,服务器端 class 实例和代码被丢弃 - 不存在!!!

你现在有这个:

所以背后的代码从来没有真正直接与用户交互。

您的代码只能在到服务器的短途旅行期间修改网页。 运行s 后面的代码 - 修改网页,然后将整个页面发送回客户端。

所以你永远不会直接与用户互动,而只会与网页互动,广告只会持续很短的时间。

这意味着什么?

这在很大程度上意味着您可能应该 运行 在网站之外与另一个来源交互的 100% 独立进程。它可以更新 table,然后说您的网站可以有一个定时器重新刷新,重新加载说每 1 或 2 秒。

而且我怀疑如果 10 个用户启动一个网页并且现在所有 10 个用户都开始访问该外部系统,那台机器是否会满意。然而,更糟糕的是什么?

好吧,代码可能会连接到那个盒子,设置一些代码来时不时地接收一些信息,但是如前所述,一旦后面的代码完成,整个网页就会被发送回客户端和服务器端代码+页面被丢弃,不再存在。

只有当您 post 再次返回时,代码广告页面才会从头开始(上次 post 返回时不存在以前的代码值或变量)。

现在,说完上面的内容了吗?

你可以有一个定时器,每 1 或 2 秒触发一次。如果你真的需要从网页到服务器的“实时”连接,那么你会考虑使用所谓的 asp.net signalR。设置起来有点麻烦,所以定时器的想法可能更容易开始。

但是,asp.net signalR 可能是最好的选择。

https://docs.microsoft.com/en-us/aspnet/signalr/overview/getting-started/introduction-to-signalr#:~:text=What%20is%20SignalR%3F%20ASP.NET%20SignalR%20is%20a%20library,process%20of%20adding%20real-time%20web%20functionality%20to%20applications.