HTML5 服务器驱动进度条
一个渲染成 4 个进度条的时钟,由服务器实时发布。
引言
本文演示了一个 html/javascript 实时进度条,由服务器更新。为了实现这一点,我们创建了一个 Spike Engine 服务器,每 100 毫秒将必要的时间分量(小时、分钟、秒和毫秒)发送给连接的客户端。 简要概括如下:
- 时间分量(小时、分钟、秒、毫秒)每 100 毫秒 从服务器发送到客户端。
- 它使用 progressbar.js 库 在客户端显示和更新进度条。
- 它在内部使用 websockets ,但通过 Spike-Engine 进行了抽象,对于较旧的浏览器,将会退回到 Flash sockets。
- 应用服务器是一个 自托管可执行文件。
- 客户端只是一个 普通的 HTML 页面,显示进度条,并且随着客户端从服务器获取发布的数据,进度条会更新。
[在线演示]
正如在上面的屏幕截图中可以看到的,小时、分钟、秒和毫秒有四个进度条。 当达到 24 小时时,小时进度条完成。 当分钟和秒的值达到 60 时,分钟和秒进度条完成。 毫秒进度条每秒完成一次。
服务器端实现
让我们从制作服务器开始。 此服务器需要执行以下几件事:
- 监听特定的端点 (IP+端口) 并创建一个发布-订阅通道,以便将消息发布到客户端。
- 以特定的频率(在我们的例子中是 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: 初始版本