xml地图|网站地图|网站标签 [设为首页] [加入收藏]

智能家电

当前位置:美高梅游戏网站 > 智能家电 > 用SignalR实现实时查看WebAPI请求日志

用SignalR实现实时查看WebAPI请求日志

来源:http://www.gd-chuangmei.com 作者:美高梅游戏网站 时间:2019-09-24 22:08

实现的原理比较直接,定义一个MessageHandler记录WebAPI的请求记录,然后将这些请求日志推送到客户端,客户端就是一个查看日志的页面,实时将请求日志展示在页面中。

这个例子的目的是演示如何在PersistentConnection类外部给Clients推送消息

图片 1

实现过程

一、服务端

服务端同时具备SignalR和WebAPI的功能,通过定义一个记录日志的MessageHandler实现对WebAPI请求的拦截,并生成请求记录,然后推送到客户端

step 1

创建一个具备WebAPI功能的站点,为了简化起见,设置Authentication为No Authentication

图片 2

step 2

创建一个DelegatingHandler,用于记录WebAPI日志,代码如下

下面代码没有涉及到SignalR的功能,日志展示是通过ILoggingDisplay接口传入

图片 3图片 4

public class LoggingHandler : DelegatingHandler     {         private static readonly string _loggingInfoKey = "loggingInfo";        private ILoggingDisplay _loggingDisplay;        public LoggingHandler(ILoggingDisplay loggingDisplay)         {             _loggingDisplay = loggingDisplay;         }        public LoggingHandler(HttpMessageHandler innerHandler, ILoggingDisplay loggingDisplay)             : base(innerHandler)         {             _loggingDisplay = loggingDisplay;         }        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)         {             LogRequestLoggingInfo;             return base.SendAsync(request, cancellationToken).ContinueWith(task =>             {                 var response = task.Result;                 LogResponseLoggingInfo;                 return response;             });         }        private void LogRequestLoggingInfo(HttpRequestMessage request)         {             var info = new ApiLoggingInfo();             info.HttpMethod = request.Method.Method;             info.UriAccessed = request.RequestUri.AbsoluteUri;             info.IpAddress = HttpContext.Current != null ? HttpContext.Current.Request.UserHostAddress : "0.0.0.0";             info.StartTime = DateTime.Now;             ExtractMessageHeadersIntoLoggingInfo(info, request.Headers.ToList;             request.Properties.Add(_loggingInfoKey, info);         }        private void LogResponseLoggingInfo(HttpResponseMessage response)         {             object loggingInfoObject = null;             if (!response.RequestMessage.Properties.TryGetValue(_loggingInfoKey, out loggingInfoObject))             {                 return;             }             var info = loggingInfoObject as ApiLoggingInfo;             if (info == null)             {                 return;             }             info.HttpMethod = response.RequestMessage.Method.ToString();             info.ResponseStatusCode = response.StatusCode;             info.ResponseStatusMessage = response.ReasonPhrase;             info.UriAccessed = response.RequestMessage.RequestUri.AbsoluteUri;             info.IpAddress = HttpContext.Current != null ? HttpContext.Current.Request.UserHostAddress : "0.0.0.0";             info.EndTime = DateTime.Now;             info.TotalTime = (info.EndTime - info.StartTime).TotalMilliseconds;             _loggingDisplay.Display;         }        private void ExtractMessageHeadersIntoLoggingInfo(ApiLoggingInfo info, List<KeyValuePair<string, IEnumerable<string>>> headers)         {             headers.ForEach(h =>             {                 var headerValues = new StringBuilder();                if (h.Value != null)                 {                     foreach (var hv in h.Value)                     {                         if (headerValues.Length > 0)                         {                             headerValues.Append(", ");                         }                         headerValues.Append;                     }                 }                 info.Headers.Add(string.Format("{0}: {1}", h.Key, headerValues.ToString;             });         }     }

LoggingHandler

step 3

引入SignalR相关packages

Install-Package Microsoft.AspNet.SignalR

新建一个PersistentConnection,代码为空即可(因为不涉及到客户端调用,推送也是在类的外部执行)

public class RequestMonitor : PersistentConnection
{
}

添加一个Startup类

public void Configuration(IAppBuilder app)
{
app.MapSignalR<RequestMonitor>("/monitor");
}

step 4

创建一个类实现ILoggingDisplay接口,用SignalR推送的方式实现这个接口

代码比较关键的部分就是通过GlobalHost.ConnectionManager获取当前应用程序的connectionContext,得到这个context就可以类似在PersistentConnection内部给clients推送消息

图片 5图片 6

public class SignalRLoggingDisplay : ILoggingDisplay     {         /// <summary>         /// PersistentConnection上下文         /// </summary>         private static IPersistentConnectionContext connectionContext = GlobalHost.ConnectionManager.GetConnectionContext<RequestMonitor>();        public void Display(ApiLoggingInfo loggingInfo)         {             var message = new StringBuilder();              message.AppendFormat("StartTime:{0},Method:{1},Url:{2},ReponseStatus:{3},TotalTime:{4}"                 , loggingInfo.StartTime, loggingInfo.HttpMethod, loggingInfo.UriAccessed, loggingInfo.ResponseStatusCode, loggingInfo.TotalTime);             message.AppendLine();             message.AppendFormat("Headers:{0},Body:{1}", string.Join(",", loggingInfo.Headers), loggingInfo.BodyContent);             connectionContext.Connection.Broadcast(message.ToString;         }

SignalRLoggingDisplay

step 5

在WebApiConfig的Register方法中添加自定义的handler

图片 7图片 8

public static void Register(HttpConfiguration config)        {            config.MapHttpAttributeRoutes();           config.Routes.MapHttpRoute(                name: "DefaultApi",                routeTemplate: "api/{controller}/{id}",                defaults: new { id = RouteParameter.Optional }            );           config.MessageHandlers.Add(new LoggingHandler(new SignalRLoggingDisplay;        }

RegisterHandler

到此完成服务端的功能实现

二、客户端

客户端只需要一个监控页面,html页面足矣,其主要功能是提供开始监控、停止监控功能,其他都是接收服务端的推送并展示功能代码。

图片 9图片 10

<!DOCTYPE html> <html> <head>     <title>Web API页面实时请求监控</title>     <meta charset="utf-8" /> </head> <body>     <h1>Web API Request Logs</h1>     <div>         <input type="button" value="start" id="btnStart"/>         <input type="button" value="stop" id="btnStop"/>         <input type="button" value="clear" id="btnClear"/>     </div>     <ul id="requests"></ul>     <script src="/Scripts/jquery-1.10.2.min.js"></script>     <script src="/Scripts/jquery.signalR-2.2.0.min.js"></script>     <script>         $(function () {             var requests = $("#requests");             var startButton = $("#btnStart");             var stopButton = $("#btnStop");             var connection = null;            enable(stopButton, false);             enable(startButton, true);            startButton.click(function () {                 startConnection();                 enable(stopButton, true);                 enable(startButton, false);             });            $("#btnClear").click(function () {                 $("#requests").children().remove();             });            stopButton.click(function () {                 stopConnection();                 enable(stopButton, false);                 enable(startButton, true);             });            function startConnection() {                 stopConnection();                 connection = $.connection("/monitor");                 connection.start()                     .fail(function () {                         console.log("connect failed");                     });                 connection.received(function  {                     data = data.replace(/rn/g, "<br/>")                     data = data.replace(/n/g, "<br/>");                     requests.append("<li>" + data + "</li>");                 });             }            function stopConnection() {                 if (connection != null){                     connection.stop();                 }             }            function enable(button, enabled) {                 if  {                     button.removeAttr("disabled");                 }                 else {                     button.attr("disabled", "disabled");                 }             }         });     </script> </body> </html>

Monitor

示例代码下载

本文由美高梅游戏网站发布于智能家电,转载请注明出处:用SignalR实现实时查看WebAPI请求日志

关键词: