gpt4 book ai didi

c# - 如何实现网页的实时数据

转载 作者:可可西里 更新时间:2023-11-01 02:59:27 24 4
gpt4 key购买 nike

(这是一个问答式的问题,旨在成为提出类似问题的人的首选资源。很多人似乎偶然发现了这样做的最佳方法,因为他们不知道所有选项。许多答案都是特定于 ASP.NET 的,但 AJAX 和其他技术在其他框架中确实有等效项,例如 socket.io 和 SignalR。)

我有一个在 ASP.NET 中实现的数据表。我想实时或接近实时地在页面上显示对此基础数据的更改。我该怎么做?

我的模型:

public class BoardGame
{
public int Id { get; set;}
public string Name { get; set;}
public string Description { get; set;}
public int Quantity { get; set;}
public double Price { get; set;}

public BoardGame() { }
public BoardGame(int id, string name, string description, int quantity, double price)
{
Id=id;
Name=name;
Description=description;
Quantity=quantity;
Price=price;
}
}

为了代替这个例子的实际数据库,我只是将数据存储在 Application 变量中。我将在我的 Global.asax.cs 的 Application_Start 函数中播种它。

var SeedData = new List<BoardGame>(){
new BoardGame(1, "Monopoly","Make your opponents go bankrupt!", 76, 15),
new BoardGame(2, "Life", "Win at the game of life.", 55, 13),
new BoardGame(3, "Candyland", "Make it through gumdrop forrest.", 97, 11)
};
Application["BoardGameDatabase"] = SeedData;

如果我使用 Web 窗体,我会用转发器显示数据。

<h1>Board Games</h1>
<asp:Repeater runat="server" ID="BoardGameRepeater" ItemType="RealTimeDemo.Models.BoardGame">
<HeaderTemplate>
<table border="1">
<tr>
<th>Id</th>
<th>Name</th>
<th>Description</th>
<th>Quantity</th>
<th>Price</th>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td><%#: Item.Id %></td>
<td><%#: Item.Name %></td>
<td><%#: Item.Description %></td>
<td><%#: Item.Quantity %></td>
<td><%#: Item.Price %></td>
</tr>
</ItemTemplate>
<FooterTemplate></table></FooterTemplate>
</asp:Repeater>

并在后面的代码中加载该数据:

protected void Page_Load(object sender, EventArgs e)
{
BoardGameRepeater.DataSource = Application["BoardGameDatabase"];
BoardGameRepeater.DataBind();
}

如果这是使用 Razor 的 MVC,它只是对模型的简单 foreach:

@model IEnumerable<RealTimeDemo.Models.BoardGame>
<h1>Board Games</h1>
<table border="1">
<tr>
<th>
@Html.DisplayNameFor(model => model.Id)
</th>
<th>
@Html.DisplayNameFor(model => model.Name)
</th>
<th>
@Html.DisplayNameFor(model => model.Description)
</th>
<th>
@Html.DisplayNameFor(model => model.Quantity)
</th>
<th>
@Html.DisplayNameFor(model => model.Price)
</th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Id)
</td>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.Description)
</td>
<td>
@Html.DisplayFor(modelItem => item.Quantity)
</td>
<td>
@Html.DisplayFor(modelItem => item.Price)
</td>
</tr>
}
</table>

让我们使用 Web Forms 来创建一个用于添加数据的小页面,这样我们就可以实时查看数据更新。我建议您创建两个浏览器窗口,以便您可以同时查看表单和表格。

<h1>Create</h1>
<asp:Label runat="server" ID="Status_Lbl" /><br />
Id: <asp:TextBox runat="server" ID="Id_Tb" /><br />
Name: <asp:TextBox runat="server" ID="Name_Tb" /><br />
Description: <asp:TextBox runat="server" ID="Description_Tb" /><br />
Quantity: <asp:TextBox runat="server" ID="Quantity_Tb" /><br />
Price: <asp:TextBox runat="server" ID="Price_Tb" /><br />
<asp:Button runat="server" ID="SubmitBtn" OnClick="SubmitBtn_Click" Text="Submit" />

以及背后的代码:

protected void SubmitBtn_Click(object sender, EventArgs e)
{
var game = new BoardGame();
game.Id = Int32.Parse(Id_Tb.Text);
game.Name = Name_Tb.Text;
game.Description = Description_Tb.Text;
game.Quantity = Int32.Parse(Quantity_Tb.Text);
game.Price = Int32.Parse(Price_Tb.Text);
var db = (List<BoardGame>)Application["BoardGameDatabase"];
db.Add(game);
Application["BoardGameDatabase"] = db;
//only for SignalR
/*var context = GlobalHost.ConnectionManager.GetHubContext<GameHub>();
context.Clients.All.addGame(game); */
}

最佳答案

信号R

这是我最想分享的答案,因为它代表了一个更简洁的实现,它是轻量级的,并且在当今的移动(数据受限)环境中运行良好。

多年来,有多种方法可以提供从服务器到客户端的“实时”数据推送(或推送数据的外观)。快速短轮询(类似于我基于 AJAX 的答案),Long Polling , Forever Frame , Server Sent Events , 和 WebSockets是用于实现此目的的不同传输机制。 SignalR是一个抽象层,能够根据客户端和服务器的能力选择合适的传输机制。使用 SignalR 最好的部分是它很简单。您不必担心传输机制,编程模型也很容易理解。

我将定义一个 SignalR 集线器,但将其留空。

public class GameHub : Hub
{
}

当我将数据添加到“数据库”时,我将运行下面的代码。如果您阅读了这个问题,您会看到我在“创建”表单中将其注释掉了。您需要取消注释。

var context = GlobalHost.ConnectionManager.GetHubContext<GameHub>();
context.Clients.All.addGame(game);

这是我的页面代码:

<h1>SignalR</h1>
<asp:Repeater runat="server" ID="BoardGameRepeater" ItemType="RealTimeDemo.Models.BoardGame">
<HeaderTemplate>
<table border="1">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Description</th>
<th>Quantity</th>
<th>Price</th>
</tr>
</thead>
<tbody id="BoardGameTblBody">
</HeaderTemplate>
<ItemTemplate>
<tr>
<td><%#: Item.Id %></td>
<td><%#: Item.Name %></td>
<td><%#: Item.Description %></td>
<td><%#: Item.Quantity %></td>
<td><%#: Item.Price %></td>
</tr>
</ItemTemplate>
<FooterTemplate></tbody></table></FooterTemplate>
</asp:Repeater>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="Scripts/jQuery-1.6.4.min.js"></script>
<script src="Scripts/jquery.signalR-2.1.1.min.js"></script>
<script src="signalr/hubs"></script>
<script type="text/javascript">
var hub = $.connection.gameHub;
hub.client.addGame = function (game) {
$("#BoardGameTblBody").append("<tr><td>" + game.Id + "</td><td>" + game.Name + "</td><td>" + game.Description + "</td><td>" + game.Quantity + "</td><td>" + game.Price + "</td></tr>");
};
$.connection.hub.start();
</script>

以及背后的代码:

protected void Page_Load(object sender, EventArgs e)
{
BoardGameRepeater.DataSource = Application["BoardGameDatabase"];
BoardGameRepeater.DataBind();
}

注意这里发生了什么。当服务器调用 context.Clients.All.addGame(game); 时,它正在为连接到游戏中心。 SignalR 负责为我连接事件,并自动将服务器上的 game 对象转换为客户端上的 game 对象。最重要的是,没有每隔几秒来回的网络流量,因此它非常轻便。

优点:

  • 网络流量非常小
  • 易于开发,但仍然灵活
  • 不随请求发送 View 状态
  • 不连续轮询服务器。

请注意,您可以在客户端为 editedGame 添加一个功能,以便轻松地将更改的数据推送到客户端(对于删除也是如此)。

关于c# - 如何实现网页的实时数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25829343/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com