构建实时服务监控面板!
我们的服务监控面板将实时显示真实数据。它将以近乎实时的、异步的、非阻塞的方式向我们展示服务器和微服务上发生的情况。
点击此处查看完整客户端示例。
观看使用D3.js可视化数据,用JavaScript阐述你的数据! 观看此课程 观看此课程 此处展示服务器演示。
我们将使用AngularJS框架和许多炫酷的实时图表以及大量实时数据来构建此监控面板的简化版本。我们还将使用.NET 4.5的SignalR和Web API库构建我们的服务。
AngularJS开箱即用地强制执行良好的应用程序开发实践。所有内容都是注入的,这意味着依赖项的耦合度低。此外,Angular在视图、模型和控制器之间具有良好的分离。
Angular在这里补充了.NET,允许服务器端代码保持小巧、易于管理和可测试。服务器端代码仅用于发挥其优势——进行繁重的处理。
将SignalR与.NET 4.5的Web API一起使用与将Node.js与Socket.IO一起使用非常相似,并允许从服务器到订阅客户端进行相同类型的非阻塞、异步推送。SignalR在底层使用WebSockets,但因为它抽象了通信,所以在Angular内部运行时,它将回退到客户端浏览器支持的任何技术。(例如,对于旧版浏览器,它可能会回退到长轮询。)
此外,借助动态标签和Json.NET的魔力,.NET框架将JavaScript视为一等公民。事实上,通过JavaScript使用Web API和SignalR技术通常比通过原生.NET客户端更容易,因为它们是考虑到JavaScript而构建的。
本教程中使用的所有AngularJS代码都可以在此处找到。
我将介绍如何使用您最喜欢的文本编辑器和纯文件夹以及Visual Studio来创建它,这取决于创建项目的工具。
文件夹和文件结构如下所示:
<code>root app (Angular应用程序特定的JavaScript) Content (CSS等) Scripts (引用的JavaScript等) ... index.html</code>
您需要下载以下文件:
在我们的Scripts文件夹中,我们需要:
在我们的Content文件夹中:
如果您觉得文本文件过于简单,则通过Visual Studio进行设置非常简单。
只需通过转到文件 -> 新建 -> 项目,然后选择Web作为模板类型来设置一个空的Web应用程序。
然后只需右键单击项目,转到管理Nuget包,搜索并下载jQuery、AngularJS、Bootstrap、D3和SignalR JavaScript客户端。
下载并安装这些后,您应该在Scripts和Contents文件夹中看到它们。此外,在已安装的Nuget包下,您将看到以下内容:
最后,Nuget不包含Epoch、ng-epoch和n3图表库,因此您需要手动添加它们。只需按照上一节中详细介绍的步骤即可获取这些库。
现在我们准备编写一些代码了。
首先,让我们创建我们的基本index.html文件,它将容纳我们的Angular JavaScript代码。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>AngularJS - SignalR - ServiceDashboard</title> <link rel="stylesheet" href="Content/bootstrap.min.css" /> <link rel="stylesheet" href="Content/epoch.min.css" /> <🎜> <🎜> <🎜> <🎜> <🎜> <🎜> <🎜> <🎜> <🎜> <🎜> <🎜> <🎜> </head> <body ng-app="angularServiceDashboard"> </body> </html>
这里有一些事情需要注意。首先,我们添加了所有依赖项以便它们加载。其次,我们引用了一些尚不存在的新文件(app文件夹中的所有文件)。我们接下来将编写这些文件。
让我们进入我们的app文件夹并创建我们的app.js文件。这是一个非常简单的文件。
<code>root app (Angular应用程序特定的JavaScript) Content (CSS等) Scripts (引用的JavaScript等) ... index.html</code>
此文件为我们做了几件事。它设置了我们的主应用程序模块angularServiceDashboard,并注入了两个外部引用——ng.epoch(这是我们的Epoch.js Angular指令)和n3-pie-chart(这是一个为Angular制作的、结构良好的图表库)。
如果您注意到,我们还为backendServerUrl注入了一个值,它当然托管在其他地方,我们计划在这里使用它。
让我们创建一个服务工厂类,它将绑定到服务器的URL。这将是我们HTML中引用的services.js文件,它将进入app文件夹:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>AngularJS - SignalR - ServiceDashboard</title> <link rel="stylesheet" href="Content/bootstrap.min.css" /> <link rel="stylesheet" href="Content/epoch.min.css" /> <🎜> <🎜> <🎜> <🎜> <🎜> <🎜> <🎜> <🎜> <🎜> <🎜> <🎜> <🎜> </head> <body ng-app="angularServiceDashboard"> </body> </html>
这段代码使用了流行的on和off(这里不需要off)订阅模式,并通过使用Angular工厂封装了与我们应用程序的SignalR的所有通信。
这段代码乍一看可能有点让人不知所措,但当我们构建控制器时,您会更好地理解它。它所做的只是获取后端SignalR服务器的URL和SignalR中心名称。(在SignalR中,您可以在同一服务器中使用多个中心来推送数据。)
此外,这段代码允许SignalR服务器(位于其他地方的某个盒子中)通过on方法调用我们的应用程序。它允许我们的应用程序通过invoke方法调用SignalR服务器内部的函数。
接下来,我们需要我们的控制器,它将把我们的数据从服务绑定到我们的作用域。让我们在我们的app文件夹中创建一个名为controllers.js的文件。
'use strict'; var app = angular.module('angularServiceDashboard', ['ng.epoch','n3-pie-chart']); app.value('backendServerUrl', 'http://sitepointsignal.cloudapp.net/');
此控制器在这里做了一些事情。它创建了我们的Angular服务对象并将其绑定一个回调函数,以便服务器在我们的控制器中调用某些内容。
您会看到,每次服务器回调我们时,我们都会遍历服务器返回的JSON数组。然后我们为每种性能类型都有一个switch语句。现在,我们将设置RAM,然后返回并填充其余部分。
至于我们的指令,我们实际上只需要一个用于我们的Epoch图表。我们将使用一个名为ng-epoch.js的开源指令,我们在我们的index.html存根文件中已经对其进行了引用。
我们可以将所有这些图表拆分为不同的指令,使用一些模板并使用UI-Router,但是为了本教程的简单起见,我们将把所有视图都放在我们的index.html文件中。
现在让我们将我们的视图添加到index.html文件中。我们可以通过在body标签下添加以下内容来实现:
'use strict'; app.factory('backendHubProxy', ['$rootScope', 'backendServerUrl', function ($rootScope, backendServerUrl) { function backendFactory(serverUrl, hubName) { var connection = $.hubConnection(backendServerUrl); var proxy = connection.createHubProxy(hubName); connection.start().done(function () { }); return { on: function (eventName, callback) { proxy.on(eventName, function (result) { $rootScope.$apply(function () { if (callback) { callback(result); } }); }); }, invoke: function (methodName, callback) { proxy.invoke(methodName) .done(function (result) { $rootScope.$apply(function () { if (callback) { callback(result); } }); }); } }; }; return backendFactory; }]);
这将简单地创建一个位置,让服务器将RAM数据推回。数据将首先进入我们的服务,然后进入控制器,最后进入视图。
它应该看起来像这样:
现在让我们添加一些图表,这正是我们真正想要做的。我们将为epoch.js时间线添加一个名为timestamp的变量。我们还将添加一个名为chartEntry的数组,我们将将其绑定到我们的epoch.ng指令。
<code>root app (Angular应用程序特定的JavaScript) Content (CSS等) Scripts (引用的JavaScript等) ... index.html</code>
然后让我们映射switch语句中的数据并添加其余所需的epoch.js数据项。当然,我们可以进一步分解它(例如,使用更多函数和过滤器),但为了本教程的简单起见,我们将保持简单。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>AngularJS - SignalR - ServiceDashboard</title> <link rel="stylesheet" href="Content/bootstrap.min.css" /> <link rel="stylesheet" href="Content/epoch.min.css" /> <🎜> <🎜> <🎜> <🎜> <🎜> <🎜> <🎜> <🎜> <🎜> <🎜> <🎜> <🎜> </head> <body ng-app="angularServiceDashboard"> </body> </html>
我们的控制器看起来更完善了。我们在作用域中添加了一个realtimeAreaFeed,我们将通过ng-epoch指令将其绑定到我们的视图,并且我们还在作用域中添加了areaAxes,它决定了区域图的布局。
现在让我们将指令添加到index.html并显示传入的CPU值数据:
'use strict'; var app = angular.module('angularServiceDashboard', ['ng.epoch','n3-pie-chart']); app.value('backendServerUrl', 'http://sitepointsignal.cloudapp.net/');
chart-class指的是D3.js的颜色方案,chart-height是您猜测的内容,chart-stream是从SignalR服务器返回的数据。
有了它,我们应该看到图表实时出现:
现在让我们将大量数据点连接到此图表,并从n3-pie框架添加另一个图表(因为谁不喜欢饼图!)。
要从n3-pie框架添加饼图,只需将以下内容添加到我们的控制器中:
'use strict'; app.factory('backendHubProxy', ['$rootScope', 'backendServerUrl', function ($rootScope, backendServerUrl) { function backendFactory(serverUrl, hubName) { var connection = $.hubConnection(backendServerUrl); var proxy = connection.createHubProxy(hubName); connection.start().done(function () { }); return { on: function (eventName, callback) { proxy.on(eventName, function (result) { $rootScope.$apply(function () { if (callback) { callback(result); } }); }); }, invoke: function (methodName, callback) { proxy.invoke(methodName) .done(function (result) { $rootScope.$apply(function () { if (callback) { callback(result); } }); }); } }; }; return backendFactory; }]);
当然,该值将由SignalR服务器更新。您可以在我们控制器的完整代码中看到这一点。
我们还应该花点时间考虑一下我们视图的完整代码。
我们应该在屏幕上看到以下数据:
我们已经看到Angular可以非常轻松地连接到SignalR——只需在AngularJS服务或工厂中插入端点即可。AngularJS工厂是一种与SignalR通信的封装机制。“结合”后,谁知道AngularJS和.NET会如此完美地协同工作?
我将介绍一些.NET代码,这些代码允许在后端进行此通信。(您可以在此处找到源代码。)
首先,要开始构建服务器代码,您需要在Visual Studio解决方案中运行SignalR。为此,只需按照ASP.NET上的优秀教程即可运行基本的SignalR解决方案。(这是最简单的。)
运行后,将C# Hub类更改为以下内容:
'use strict'; app.controller('PerformanceDataController', ['$scope', 'backendHubProxy', function ($scope, backendHubProxy) { console.log('trying to connect to service') var performanceDataHub = backendHubProxy(backendHubProxy.defaultServer, 'performanceHub'); console.log('connected to service') $scope.currentRamNumber = 68; performanceDataHub.on('broadcastPerformance', function (data) { data.forEach(function (dataItem) { switch(dataItem.categoryName) { case 'Processor': break; case 'Memory': $scope.currentRamNumber = dataItem.value; break; case 'Network In': break; case 'Network Out': break; case 'Disk Read Bytes/Sec': break; case 'Disk Write Bytes/Sec': break; default: //default code block break; } }); }); } ]);
更改Hub类后,Visual Studio将报错,您需要添加一个性能模型(由于Json.NET,它在服务器推送时会自动转换为JSON):
<code>root app (Angular应用程序特定的JavaScript) Content (CSS等) Scripts (引用的JavaScript等) ... index.html</code>
JsonProperty元数据只是告诉Json.NET在为此模型转换为JSON时自动将属性名称转换为小写。JavaScript喜欢小写。
让我们添加一个PerformanceEngine类,它将通过SignalR将真实性能数据推送到任何侦听的客户端。该引擎通过异步后台线程通过SignalR向任何侦听的客户端发送这些消息。
由于其长度,您可以在我们的GitHub存储库中找到代码。
此代码基本上在每次while迭代中将一系列性能指标推送到任何已订阅的客户端。这些性能指标被注入到构造函数中。从服务器推送的速度在构造函数参数pollIntervalMillis上设置。
请注意,如果您使用OWIN作为自托管来托管SignalR,这将运行良好,如果您使用Web工作线程,它也应该运行良好。
最后要做的事情当然是在服务的OnStart()或Startup类中的某个地方启动后台线程。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>AngularJS - SignalR - ServiceDashboard</title> <link rel="stylesheet" href="Content/bootstrap.min.css" /> <link rel="stylesheet" href="Content/epoch.min.css" /> <🎜> <🎜> <🎜> <🎜> <🎜> <🎜> <🎜> <🎜> <🎜> <🎜> <🎜> <🎜> </head> <body ng-app="angularServiceDashboard"> </body> </html>
启动后台线程的两行代码(正如您猜到的那样)是我们实例化PerformanceEngine和调用OnPerformanceMonitor()的地方。
现在,我知道您可能认为我正在随机化来自服务器的数据,这是事实。但是要推送真实指标,只需使用System.Diagnostics库和Windows提供的PerformanceCounter即可。我试图保持简单,但这就是代码的样子:
'use strict'; var app = angular.module('angularServiceDashboard', ['ng.epoch','n3-pie-chart']); app.value('backendServerUrl', 'http://sitepointsignal.cloudapp.net/');
我们已经了解了如何通过Angular使用SignalR数据,并且我们已经将该数据连接到Angular端的实时图表框架。
此处显示客户端最终版本的演示,您可以从此处获取代码。
此处显示服务器最终版本的演示,您可以从此处获取代码。
我希望您喜欢这个演练。如果您尝试过类似的方法,请在评论中告诉我们!
在AngularJS中设置SignalR涉及几个步骤。首先,您需要使用NuGet或npm安装SignalR库。安装后,您可以在服务器上创建一个新的SignalR中心。此中心将负责发送和接收消息。在客户端,您需要引用SignalR JavaScript库并创建到您的中心的连接。然后,您可以启动连接并定义处理传入消息的函数。
SignalR提供了一种处理连接错误的内置机制。您可以使用中心连接上的.error()函数来定义一个回调函数,该函数将在发生错误时调用。此回调函数可以向用户显示错误消息或尝试重新连接到中心。
是的,SignalR可以与任何支持AJAX和WebSockets的JavaScript框架一起使用。这包括流行的框架,如React、Vue.js和Angular。您只需要将SignalR JavaScript库包含在您的项目中并像在任何其他JavaScript应用程序中一样创建一个中心连接即可。
要将消息从服务器发送到客户端,您可以使用中心的Clients属性。此属性提供方法,用于将消息发送到所有连接的客户端、特定客户端或客户端组。您可以从服务器代码的任何部分调用这些方法,以将实时更新发送到您的客户端。
SignalR提供了几个保护应用程序的选项。您可以使用[Authorize]属性来限制对您的中心和中心方法的访问。您还可以使用Global.asax文件中的MapHubs()方法为您的中心指定自定义授权器。此外,您可以使用SSL来加密SignalR流量并防止窃听。
SignalR会自动处理断开连接并尝试重新连接。但是,您也可以使用中心连接上的.disconnected()函数手动处理断开连接。此函数允许您定义一个回调函数,该函数将在连接丢失时调用。
SignalR是一个.NET库,旨在与.NET服务器一起使用。但是,可以通过使用兼容的WebSocket库在非.NET服务器上使用SignalR。您需要在服务器上实现SignalR协议并自行处理连接和消息传递逻辑。
您可以使用Postman或Fiddler等工具向您的中心发送HTTP请求并验证响应来测试您的SignalR应用程序。您还可以为您的中心方法和客户端函数编写单元测试。
是的,您可以在移动应用程序中使用SignalR。SignalR JavaScript库可以在使用Cordova或Ionic构建的混合移动应用程序中使用。对于原生移动应用程序,iOS和Android都提供了SignalR客户端。
SignalR提供了几个扩展应用程序的选项。您可以使用Azure SignalR服务,这是一个完全托管的服务,它为您处理所有SignalR连接。您还可以使用后端,这是一个软件层,用于在多个服务器之间分发消息。
以上是用AngularJS构建实时信号仪表板的详细内容。更多信息请关注PHP中文网其他相关文章!