65.9K
CodeProject 正在变化。 阅读更多。
Home

HTML5 服务器驱动进度条

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.90/5 (9投票s)

2014年6月18日

CPOL

3分钟阅读

viewsIcon

31690

downloadIcon

508

一个渲染成 4 个进度条的时钟,由服务器实时发布。

引言

本文演示了一个 html/javascript 实时进度条,由服务器更新。为了实现这一点,我们创建了一个 Spike Engine 服务器,每 100 毫秒将必要的时间分量(小时、分钟、秒和毫秒)发送给连接的客户端。 简要概括如下:

  1. 时间分量(小时、分钟、秒、毫秒)每 100 毫秒 从服务器发送到客户端。
  2. 它使用 progressbar.js 在客户端显示和更新进度条。
  3. 它在内部使用 websockets ,但通过 Spike-Engine 进行了抽象,对于较旧的浏览器,将会退回到 Flash sockets。
  4. 应用服务器是一个 自托管可执行文件
  5. 客户端只是一个 普通的 HTML 页面,显示进度条,并且随着客户端从服务器获取发布的数据,进度条会更新。

[在线演示]

正如在上面的屏幕截图中可以看到的,小时、分钟、秒和毫秒有四个进度条。 当达到 24 小时时,小时进度条完成。 当分钟和秒的值达到 60 时,分钟和秒进度条完成。 毫秒进度条每秒完成一次。

服务器端实现

让我们从制作服务器开始。 此服务器需要执行以下几件事:

  1. 监听特定的端点 (IP+端口) 并创建一个发布-订阅通道,以便将消息发布到客户端。
  2. 以特定的频率(在我们的例子中是 100 毫秒)获取时间分量 并将该值 发布 到所有订阅的客户端。

对于第一项任务,我们需要调用 Service.Listen 方法,以便开始监听特定的 IPAddress 和端口(称为端点)。 Main 方法中的这一行实现了它:

Service.Listen(new TcpBinding(IPAddress.Any, 8002));

接下来,我们使用 Spike-Engine using 语句创建一个新的 PubHub 实例。

var hub = Service.Hubs.GetOrCreatePubHub("Clock");

这实现了发布-订阅模型。 在发布-订阅模型中,消息的发送者(称为发布者)不会对消息进行编程,使其直接发送给特定的接收者(称为订阅者)。 相反,已发布的消息被分类到类中,而不知道可能存在哪些订阅者(如果有)。 同样,订阅者对一个或多个类表示兴趣,并且只接收他们感兴趣的消息,而不知道可能存在哪些发布者(如果有)。 我们首先创建我们的 PubHub 实例,并 为其指定名称。 这个名字很重要,因为当我们想要订阅时,我们需要在我们的客户端中提供相同的名称。

然后,我们安排一个函数每 100 毫秒调用一次,此函数会将消息发布到 PubHub。

hub.Schedule(TimeSpan.FromMilliseconds(100), OnTick);

它看起来是这样的

[InvokeAt(InvokeAtType.Initialize)]
public static void Initialize()
{
   // We create a PubHub which acts as publish-subscribe channel. This allows us to publish
   // simple string messages and remote clients can subscribe to the publish notifications
   var hub = Service.Hubs.GetOrCreatePubHub("Clock");

   // We schedule the OnTick() function to be executed every 100 milliseconds.
   hub.Schedule(TimeSpan.FromMilliseconds(100), OnTick);
}

以下是发布消息的完整函数的样子。 它非常简单,因为我们只需调用 Publish 方法。 您可能会注意到,我们不必担心要传输给消费者的字典的序列化。 该方法接受一个对象,并使用 JSON 格式自动序列化它。

private static void OnTick(IHub hub)
{
   // Cast is as Pubhub
   var pubHub = hub as PubHub;
   if (pubHub != null)
   {
       // Get the current time and push it into the dictionary
       var dateTime = DateTime.Now;
       var time = new Dictionary<string, int>();
       time.Add("hours", dateTime.Hour);
       time.Add("minutes", dateTime.Minute);
       time.Add("seconds", dateTime.Second);
       time.Add("milliseconds", dateTime.Millisecond);

       // Publish data
       pubHub.Publish(time);
    }
}

客户端实现

现在,我们必须创建一个客户端,它将使用我们的服务器发布的数据,并在 html 页面中呈现进度条。 为此,我们使用了 progressbar.js 库来显示进度条。

我们首先在我们的页面中添加所需的 javascript 引用。

<script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
<script src="Scripts/progressbar.min.js" type="text/javascript"></script>
<script src="Scripts/spike-sdk.min.js" type="text/javascript"></script>

然后,我们创建将在其中显示进度条的 div。

<div id="divHoursProgressBar"></div>
<div id="divMinutesProgressBar"></div>
<div id="divSecondsProgressBar"></div>
<div id="divMillisecondsProgressBar"></div>

接下来,我们在 javascript 中实现客户端功能。 要从服务器获取发布的数据,我们需要连接到服务器。 当客户端连接到服务器时,它会订阅 Clock hub,因为它是指定的名称。

var server = new spike.ServerChannel("127.0.0.1:8002");

// Once the browser is connected to the server, subscribe.
server.on('connect', function() {
    server.hubSubscribe('Clock', null);
});

一旦在客户端接收到发布的数据,我们就会调用负责处理进度条的函数“setStatus”。

// When we got a notification from the server
server.on('hubEventInform', function(p) {
    setStatus(p.message);
});

function setStatus(timeComponents) 
{
    var parsedTimeComponents = JSON.parse(timeComponents);

    // Handle hours progress bar
    var hours = parsedTimeComponents.hours;
    var hoursProgressBarPercent = hours / .24;
    document.getElementById('lblHoursCount').innerHTML = hours;
    hoursProgressBar.setPercent(hoursProgressBarPercent);

    // Handle minutes progress bar
    var minutes = parsedTimeComponents.minutes;
    var minutesProgressBarPercent = minutes / .6;
    document.getElementById('lblMinutesCount').innerHTML = minutes;
    minutesProgressBar.setPercent(minutesProgressBarPercent);

    // Handle seconds progress bar
    var seconds = parsedTimeComponents.seconds;
    var secondsProgressBarPercent = seconds / .6;
    document.getElementById('lblSecondsCount').innerHTML = seconds;
    secondsProgressBar.setPercent(secondsProgressBarPercent);

    // Handle milliseconds progress bar
    var milliseconds = parsedTimeComponents.milliseconds;
    var millisecondsProgressBarPercent = milliseconds / 10;
    document.getElementById('lblMillisecondsCount').innerHTML = milliseconds;
    millisecondsProgressBar.setPercent(millisecondsProgressBarPercent);
}

历史

  • 2015/06/23: 源代码和文章更新到 Spike v3
  • 2014/06/18: 初始版本
© . All rights reserved.