深入理解WebHook及其在ASP.NET MVC中的应用

WebHook是一种基于HTTP的回调机制,它允许服务之间通过发布/订阅模型进行通信,而无需服务之间进行周期性的API调用。当服务中发生事件时,会以HTTP POST请求的形式向注册的订阅者发送通知,POST请求中包含了事件的相关信息,使得接收者能够据此采取相应的行动。

WebHook采用发布-订阅消息模式,消息的发送者称为发布者(publishers),接收者称为订阅者(subscribers)。WebHook的主要优势在于,应用程序不需要周期性地调用API,相反,API会在特定端点调用应用程序,通知发生了某些有趣的事件。

在项目中实现自定义WebHook的需求促使深入了解了WebHook的实现方式。在一个ASP.NET MVC5.0的项目中实现了自定义WebHook。由于项目需求,需要在当前的代码库中实现自定义WebHook。幸运的是,Microsoft提供了一个名为Microsoft.AspNet.WebHooks.Custom.dll的库,它极大地简化了工作。

在实现过程中,遇到了一个问题:在演示服务器上,将WebHook信息存储在内存中是可行的,但在生产环境中,需要将WebHook信息存储在持久化存储中。由于应用程序将部署在不同的服务器上,不能使用Azure表存储。因此,需要找到一种方法来实现这一目标。

在编写本文时,得知有一个更新,即Microsoft.AspNet.WebHooks.Custom.SqlStorage.dll,它允许将WebHook信息存储在SQL Server中。但在实现时,这个库尚未发布,因此需要自己编写机制来实现持久化存储。

通过实现一个接口IWebHookStore来管理WebHook订阅,这个接口提供了查询、插入、更新和删除订阅的抽象。默认的IWebHookStore实现仅在内存中进行操作。想法是编写一个类来实现IWebHookStore接口,并将依赖项传递给WebHookManager。

以下是创建的持久化存储类的示例代码,并将其实例传递给WebHookManager:

C# IWebHookStore _whStore = new PersistentWebHookStore(); IWebHookManager _whManager = new WebHookManager(_whStore, new TraceLogger());

接下来,将编写PersistentWebHookStore类并实现Microsoft.AspNet.WebHooks中的IWebHookStore接口。

C# namespace Microsoft.AspNet.WebHooks { public interface IWebHookStore { Task DeleteAllWebHooksAsync(string user); Task<StoreResult> DeleteWebHookAsync(string user, string id); Task<ICollection<WebHook>> GetAllWebHooksAsync(string user); Task<StoreResult> InsertWebHookAsync(string user, WebHook webHook); Task<WebHook> LookupWebHookAsync(string user, string id); Task<ICollection<WebHook>> QueryWebHooksAsync(string user, IEnumerable<string> actions); Task<StoreResult> UpdateWebHookAsync(string user, WebHook webHook); } }

PersistentWebHookStore类实现了IWebHookStore接口,提供了持久化存储WebHook的方法。以下是PersistentWebHookStore类的一部分实现:

C# public class PersistentWebHookStore : IWebHookStore { #region Member Variables private readonly IWebHookRepository _webHookRepository = null; #endregion #region Constructor public PersistentWebHookStore() { _webHookRepository = new WebHookRepository(); } #endregion #region IWebHookStore Methods public Task<StoreResult> InsertWebHookAsync(string user, WebHook webHook) { if (!string.IsNullOrWhiteSpace(user) && webHook != null) { user = Normalize(user); bool isInserted = _webHookRepository.Insert(user, webHook); StoreResult result = isInserted ? StoreResult.Success : StoreResult.Conflict; return Task.FromResult(result); } else { throw new Exception("Values expected for either user or webHook"); } } // ... 其他方法的实现 ... #endregion }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485