如何实现为一个网页的实时数据 [英] How to implement real time data for a web page

查看:206
本文介绍了如何实现为一个网页的实时数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(此的目的是作为一个Q / A作风问题,打算做个中间人,以资源为人们问类似的问题,很多人似乎无意中发现这样做是因为他们不知道的最好的方法所有的选项,很多问题的答案将是ASP.NET特异性,但AJAX等技术并具有等效于其他框架,如插座.IO 并SignalR。)

我有我在ASP.NET中实现的数据表。我想显示在实时或接近实时地改变此基础数据在页面上。我该如何去做?

我的模型:

 公共类桌上游戏
    {
    公众诠释编号{获得;组;}
    公共字符串名称{;组;}
    公共字符串描述{获得;组;}
    公众诠释数量{获得;组;}
    公共双价{获得;组;}

    公共桌上游戏(){}
    公共桌上游戏(INT ID,字符串名称,字符串描述,诠释数量,双重价格)
        {
        ID = ID;
        名称=名称;
        说明=描述;
        数量=数量;
        价格=价格;
        }
    }
 

在代替在这个例子中一个实际的数据库中,我只是将数据存储在应用程序变量。我将它的种子在我的Global.asax.cs我的的Application_Start 的功能。

  VAR SeedData =新的名单,其中,桌上游戏>(){
    新的桌上游戏(1,大富翁,让你的对手破产!,76,15),
    新的桌上游戏(2,生命,赢在人生的游戏。,55,13),
    新的桌上游戏(3,Candyland,通过gumdrop阿甘做到这一点。,97,11)
    };
应用[BoardGameDatabase] = SeedData;
 

如果我是使用Web窗体,我会用一个中继器显示的数据。

 < H1>董事会游戏< / H1>
        < ASP:直放站=服务器ID =BoardGameRepeater的ItemType =RealTimeDemo.Models.BoardGame>
            < HeaderTemplate中>
                <表格边框=1>
                    &其中; TR>
                        百分位> ID和LT; /第i个
                        百分位>名称< /第i个
                        百分位>简介< /第i个
                        百分位>数量< /第i个
                        百分位>价格< /第i个
                    < / TR>
            < / HeaderTemplate中>
            <的ItemTemplate>
                &其中; TR>
                    &其中; TD>&所述;%#:Item.Id%GT;&所述; / TD>
                    &其中; TD>&所述;%#:Item.Name%GT;&所述; / TD>
                    &其中; TD>&所述;%#:Item.Description%GT;&所述; / TD>
                    &其中; TD>&所述;%#:Item.Quantity%GT;&所述; / TD>
                    &其中; TD>&所述;%#:Item.Price%GT;&所述; / TD>
                < / TR>
            < / ItemTemplate中>
            < FooterTemplate>< /表>< / FooterTemplate>
        < / ASP:直放站>
 

和加载数据的背后,code:

 保护无效的Page_Load(对象发件人,EventArgs的)
    {
    BoardGameRepeater.DataSource =申请[BoardGameDatabase];
    BoardGameRepeater.DataBind();
    }
 

如果这还用剃刀MVC,它只是一个简单的foreach在模型:

  @model IEnumerable的< RealTimeDemo.Models.BoardGame>
< H1>董事会游戏< / H1>
<表格边框=1>
    &其中; TR>
        <第i个
            @ Html.DisplayNameFor(型号=> model.Id)
        < /第i个
        <第i个
            @ Html.DisplayNameFor(型号=> model.Name)
        < /第i个
        <第i个
            @ Html.DisplayNameFor(型号=> model.Description)
        < /第i个
        <第i个
            @ Html.DisplayNameFor(型号=> model.Quantity)
        < /第i个
        <第i个
            @ Html.DisplayNameFor(型号=> model.Price)
        < /第i个
    < / TR>
@foreach(以模型的VaR项){
    &其中; 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>
}
< /表>
 

让我们使用Web窗体有添加数据一点点页面,所以我们就可以观看实时的数据更新。我建议你​​创建两个浏览器窗口,所以你可以看到在同一时间的表格和表格。

 < H1>创建< / H1>
< ASP:标签=服务器ID =Status_Lbl/>< BR />
编号:LT; ASP:文本框=服务器ID =Id_Tb/>< BR />
名称:< ASP:文本框=服务器ID =Name_Tb/>< BR />
说明:LT; ASP:文本框=服务器ID =Description_Tb/>< BR />
数量:< ASP:文本框=服务器ID =Quantity_Tb/>< BR />
价格:< ASP:文本框=服务器ID =Price_Tb/>< BR />
< ASP:按钮=服务器ID =SubmitBtn的OnClick =SubmitBtn_Click文本=提交/>
 

和后面的code:

 保护无效SubmitBtn_Click(对象发件人,EventArgs的)
    {
    VAR游戏=新的桌上游戏();
    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 =(名单<桌上游戏>)的应用[BoardGameDatabase];
    db.Add(游戏);
    应用[BoardGameDatabase] = DB;
    //只为SignalR
    / * VAR背景= GlobalHost.ConnectionManager.GetHubContext< GameHub>();
    context.Clients.All.addGame(游戏); * /
    }
 

解决方案

SignalR

这是我最兴奋,分享答案,因为它重新presents一个更清洁的实现,是轻量级的,在今天的移动效果很好(数据戋)环境。

已经有几个方法,多年来为客户提供实时从服务器推数据到客户端(或推数据的外观)。快速短轮询(类似我的基于AJAX的答案)的长轮询永远框架,的服务器发送的事件和的的WebSockets 是用来实现这种不同的传输机制。 SignalR 是能够选择基于客户机和服务器的能力上的适当的传输机制的一个抽象层。使用SignalR的最好的部分是它的简单。你不必担心传输机制,而编程模型很容易理解。

我要定义一个SignalR中心,而只是把它空。

 公共类GameHub:集线器
    {
    }
 

当我将数据添加到数据库,我要运行以下位code。如果你读的问题,你会看到我评论是在创造的形式。您将要取消注释。

  VAR上下文= GlobalHost.ConnectionManager.GetHubContext< GameHub>();
context.Clients.All.addGame(游戏);
 

这是我的第code:

 < H1> SignalR< / H1>
        < ASP:直放站=服务器ID =BoardGameRepeater的ItemType =RealTimeDemo.Models.BoardGame>
            < HeaderTemplate中>
                <表格边框=1>
                    < THEAD>
                        &其中; TR>
                            百分位> ID和LT; /第i个
                            百分位>名称< /第i个
                            百分位>简介< /第i个
                            百分位>数量< /第i个
                            百分位>价格< /第i个
                        < / TR>
                    < / THEAD>
                    < TBODY ID =BoardGameTblBody>
            < / HeaderTemplate中>
            <的ItemTemplate>
                &其中; TR>
                    &其中; TD>&所述;%#:Item.Id%GT;&所述; / TD>
                    &其中; TD>&所述;%#:Item.Name%GT;&所述; / TD>
                    &其中; TD>&所述;%#:Item.Description%GT;&所述; / TD>
                    &其中; TD>&所述;%#:Item.Quantity%GT;&所述; / TD>
                    &其中; TD>&所述;%#:Item.Price%GT;&所述; / TD>
                < / TR>
            < / ItemTemplate中>
            < FooterTemplate>< / TBODY>< /表>< / FooterTemplate>
        < / ASP:直放站>
        &LT;脚本的src =// ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
        &LT;脚本SRC =脚本/ jQuery的-1.6.4.min.js&GT;&LT; / SCRIPT&GT;
        &LT;脚本SRC =脚本/ jquery.signalR-2.1.1.min.js&GT;&LT; / SCRIPT&GT;
        &LT;脚本SRC =signalr /集线器&GT;&LT; / SCRIPT&GT;
        &LT;脚本类型=文/ JavaScript的&GT;
            VAR枢纽= $ .connection.gameHub;
            hub.client.addGame =功能(游戏){
                $(#BoardGameTblBody)附加(&其中; TR&GT;&其中; TD&gt;中+ game.Id +&所述; / TD&GT;&其中; TD&gt;中+ game.Name +&所述; / TD&GT;&其中; TD&GT ;+ game.Description +&所述; / TD&GT;&其中; TD&gt;中+ game.Quantity +&所述; / TD&GT;&其中; TD&gt;中+ game.Price +&所述; / TD&GT;&所述; / TR&GT; );
            };
            $ .connection.hub.start();
        &LT; / SCRIPT&GT;
 

和后面的code:

 保护无效的Page_Load(对象发件人,EventArgs的)
        {
        BoardGameRepeater.DataSource =申请[BoardGameDatabase];
        BoardGameRepeater.DataBind();
        }
 

注意这里发生了什么。当服务器调用 context.Clients.All.addGame(游戏); 它执行的是被分配到 hub.client.addGame 对于连接到GameHub每一个客户端。 SignalR正在连线了事件对我的关怀,并自动将我的游戏对象的服务器上的游戏对象在客户端上。最重要的是,有没有网络通信来回每隔几秒钟,所以这是令人难以置信的轻巧。

优势:

  • 在网络流量很轻
  • 易于开发,但仍然灵活
  • 在不发送视图状态的要求
  • 在不进行连续轮询服务器。

请注意,你可以添加一个功能,在客户端上的 editedGame 推送更改的数据输出到客户端轻松(同为删除)。

(This is intended as a Q/A style question, intended to be a go-to resource for people that ask similar questions. A lot of people seem to stumble on the best way of doing this because they don't know all the options. Many of the answers will be ASP.NET specific, but AJAX and other techniques do have equivalents in other frameworks, such as socket.io and SignalR.)

I have a table of data that I have implemented in ASP.NET. I want to display changes to this underlying data on the page in real time or near real time. How do I go about it?

My Model:

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

In lieu of an actual database for this example, I'm just going to store the data in the Application variable. I'm going to seed it in my Application_Start function of my Global.asax.cs.

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;

If I were using Web Forms, I'd display the data with a repeater.

<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>

And load that data in the code behind:

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

If this were MVC using Razor, it's just a simple foreach over the model:

@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>

Let's use Web Forms to have a little page for adding data so we can then watch the data update in real time. I recommend you create two browser windows so you can see the form and table at the same time.

<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" />

And the code behind:

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); */           
    }

解决方案

SignalR

This is the answer I'm most excited to share, because it represents a much cleaner implementation that is lightweight and works well in today's mobile (data constricted) environment.

There have been several methods over the years to provide "realtime" pushing of data from the server to the client (or the appearance of pushing data). Rapid Short Polling (similar to my AJAX based answers), Long Polling, Forever Frame, Server Sent Events, and WebSockets are different transport mechanisms used to achieve this. SignalR is an abstraction layer capable of selecting an appropriate transport mechanism based on the client and server's capabilities. The best part of using SignalR is that it's simple. You don't have to worry about the transport mechanism, and the programming model is easy to understand.

I'm going to define a SignalR hub, but just leave it empty.

public class GameHub : Hub
    {
    }

When I add data to the "database", I'm going to run the below bit of code. If you read the question, you'll see I commented it out in the "create" form. You'll want to uncomment that.

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

Here's my page code:

<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>

And the code behind:

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

Notice what's happening here. When the server calls context.Clients.All.addGame(game); it's executing the function that's been assigned to hub.client.addGame for every client that is connected to the GameHub. SignalR is taking care of wiring up the events for me, and automatically converting my game object on the server to the game object on the client. And best of all, there's no network traffic back and forth every few seconds, so it's incredibly lightweight.

Advantages:

  • Very light on the network traffic
  • Easy to develop, but still flexible
  • Doesn't send viewstate with the request
  • Doesn't poll the server continuously.

Note, you could add a function on the client for editedGame for pushing changed data out to the client easily (same for delete).

这篇关于如何实现为一个网页的实时数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆