前言

  好久没写博客了。前阶段看了下Hangfire组件,后来对其代码比较感兴趣,当时不太了解他如何生成的页面和一些访问请求等。后来看了下源代码,发现原来是 OWIN 在搞怪。于是乎开始深入研究Hangfire源代码,当然只是Route和Razor部分,具体他的核心业务后台执行任务我没研究。因为,我想到了之前做的LayIM的一个对接。那时候写的代码和项目耦合度太高,于是冒出一个写LayIM Owin插件的想法。直接开工吧。

开工

  主要参考了Hangfire的Dashboard部分。https://github.com/HangfireIO/Hangfire/tree/master/src/Hangfire.Core/Dashboard

  与之前的代码相比,这些代码都没有放入WebUI 端中,而且,分层也比较少。就一个 Owin中间件和SqlServer的实现。代码结构如下:(我自己当然写不出啦,参考上文链接中的代码)

  

  用过OWIN的都知道,就是通过IAppBuilder接口注册中间件。其实还是挺复杂的,虽然照着写了出来。为了避免误导观众,我就不多解释了。不过路由那一块我我可以说一下我的理解。

  首先定义路由集合,集合中包含所有注册的路径和实现 ILayIMDispatcher 接口的 Dispatcher。

  

  public class RouteCollection
{
private readonly List<Tuple<string, ILayimDispatcher>> _dispatchers = new List<Tuple<string, ILayimDispatcher>>(); /// <summary>
/// 注册路由
/// </summary>
/// <param name="pathTemplate">路由地址</param>
/// <param name="dispatcher">处理方法</param>
public void Add(string pathTemplate, ILayimDispatcher dispatcher)
{
Error.ThrowIfNull(pathTemplate, nameof(pathTemplate));
Error.ThrowIfNull(dispatcher, nameof(dispatcher)); _dispatchers.Add(new Tuple<string, ILayimDispatcher>(pathTemplate, dispatcher));
} /// <summary>
/// 根据Path寻找对应的Dispatcher
/// 通过正则表达式来找到匹配的结果
/// </summary>
/// <param name="path">路径</param>
/// <returns></returns>
public Tuple<ILayimDispatcher, Match> FindDispatcher(string path)
{
if (path.Length == ) path = "/"; foreach (var dispatcher in _dispatchers)
{
var pattern = dispatcher.Item1; if (!pattern.StartsWith("^", StringComparison.OrdinalIgnoreCase)) {
pattern = $"^{pattern}";
} if (!pattern.EndsWith("$", StringComparison.OrdinalIgnoreCase)) {
pattern += "$";
} var match = Regex.Match(path, pattern, RegexOptions.CultureInvariant | RegexOptions.IgnoreCase | RegexOptions.Singleline); if (match.Success) {
return new Tuple<ILayimDispatcher, Match>(dispatcher.Item2, match);
}
}
return null;
}
}

  请求,进入中间件的处理代码:

                var owinContext = new OwinContext(env);
var context = new OwinLayimContext(storage,options, env); var path = owinContext.Request.Path.Value; //匹配路由
var findResult = routes.FindDispatcher(path);
//如果没有匹配到,执行下一个
if (findResult == null) {
return next(env);
} //匹配成功之后执行 Dispatch
context.UriMatch = findResult.Item2;
//执行具体disptach方法,返回相应结果
return findResult.Item1.Dispatch(context);

  举例来说:Layim中的初始化接口。定义为 /init  需要参数为 id. 那么在路由中,注册如下:

       //AddQuery只是又封装了一层,内部还是调用了Add方法。
Routes.AddQuery<long>("/init", "id", (context, uid) =>
{
//返回处理结果
});

  在上边的例子中,AddQuery方法,注册了一个 SingleParameterQueryDispatcher<T> 的处理类。 他的作用就是处理拥有单个参数的类型为T的请求。具体代码如下:

        public async Task Dispatch(LayimContext context)
{
var request = context.Request;
var response = context.Response; var parameterValue = request.GetQuery(_parameterName);
//如果不是Get请求,返回方法不允许
if (!CommandMethod.Equals(request.Method, StringComparison.OrdinalIgnoreCase))
{
response.StatusCode = (int)HttpStatusCode.MethodNotAllowed;
await Task.FromResult(false);
}
//返回结果为"application/json";
context.Response.ContentType = "application/json";
//将参数转化为相应的类型,有 null 异常
T value = (T)Convert.ChangeType(parameterValue, typeof(T));
//执行具体处理函数
var result = _command(context, value);
//序列化结果
var json = context.Options.Serializer.SerializeObject(result);
//返回
await context.Response.WriteAsync(json);
}

总结

  简单了介绍一下路由部分的内容,相信很多小伙伴也是看的云里雾里的。看懂OWIN机制,就能够懂了。我也是大部分借鉴(抄袭)了Hangfire中的代码。

  基本思路:

  1. 注册路由
  2. 实现路由匹配方法
  3. 找到对应的处理器
  4. 处理方法,返回结果

  在不懂的话,建议直接阅读源代码,阅读源代码能有意想不到的收获。

附:LayIM.NetClient中间件的使用方法。其中IM通讯我使用了融云,所以在其中也做了一些封装。

  

 public class Startup
{
public void Configuration(IAppBuilder app)
{
//使用SQL Server
GlobalConfiguration.Configuration.UseSqlServer("LayIM_Connection"); //使用layim api 6tnym1brnmpt7
app.UseLayimApi("/layim", new LayimOptions
{
RongCloudSetting = new RongCloudSetting()
});
}
}

  LayIM中注册的路由如下:

  

  运行结果:

  

  

  获取融云token的方法:

  

  

  代码运行正常

  

  最后:我觉得Owin中间件真的很方便。首先能够避免web项目中写太多的重复的业务逻辑。(当然,layim部分抽出成api也可以)  通过封装成 LayIM.NetClient中间件以后,不管是webform还是mvc都可以通过Owin来适配。后边还会继续完善。今天就到此为止吧~~

LayIM.NetClient 组件开发记录的更多相关文章

  1. 干货!手把手教你如何使用第三方通讯服务实现LayIM Socket组件开发。

    前言 之前写了一系列的文章,是关于使用ASP.NET SignalR技术实现LayIM的功能对接,有兴趣的同学移步:http://www.cnblogs.com/panzi/p/5767095.htm ...

  2. 饿了么基于Vue2.0的通用组件开发之路(分享会记录)

    Element:一套通用组件库的开发之路 Element 是由饿了么UED设计.饿了么大前端开发的一套基于 Vue 2.0 的桌面端组件库.今天我们要分享的就是开发 Element 的一些心得. 官网 ...

  3. 每天记录一点:NetCore获得配置文件 appsettings.json vue-router页面传值及接收值 详解webpack + vue + node 打造单页面(入门篇) 30分钟手把手教你学webpack实战 vue.js+webpack模块管理及组件开发

    每天记录一点:NetCore获得配置文件 appsettings.json   用NetCore做项目如果用EF  ORM在网上有很多的配置连接字符串,读取以及使用方法 由于很多朋友用的其他ORM如S ...

  4. java 组件开发中的日志记录问题

    今天帮别人写封装几个url 请求,打成jar 包,可以以java接口的方式提供给外部访问. 遇到两个问题: 1. 是否把依赖的jar包也 打入 我要生成的jar包中,如果你不打入,别人直接调用接口会报 ...

  5. React 实践记录 01 组件开发入门

    Introduction 本文组成: Ryan Clark文章Getting started with React的翻译. 博主的实践心得. React由Facebook的程序员创建,是一个非常强大的 ...

  6. Vue (三) --- Vue 组件开发

    ------------------------------------------------------------------好心情,会让你峰回路转. 5. 组件化开发 5.1 组件[compo ...

  7. LayIM.AspNetCore Middleware 开发日记(一)闲言碎语

    前言 前几天写博客的时候突然看见了历史上的今天.不禁感慨时光如梭,这系列博客后来被我标注了已经过时,但是还有很多小伙伴咨询我.既然过时就要更新,正好 .NET Core 也出来很久了,于是乎想到把La ...

  8. Vue组件开发实践之scopedSlot的传递

    收录待用,修改转载已取得腾讯云授权 导语 现今的前端开发都讲究模块化组件化,即把公共的交互和功能封装到一个个的组件之中,在开发整体界面的时候就能像搭积木一样快速清晰高效.在使用Vue开发我们的vhtm ...

  9. [Asp.net core 3.1] 通过一个小组件熟悉Blazor服务端组件开发

    通过一个小组件,熟悉 Blazor 服务端组件开发.github 一.环境搭建 vs2019 16.4, asp.net core 3.1 新建 Blazor 应用,选择 asp.net core 3 ...

随机推荐

  1. css常用左右布局方案整理

     实际项目开发过程中我们经常会遇到页面div左右布局的需求:左侧 div 固定宽度,右侧 div 自适应宽度,填充满剩余页面,下面整理几种常用的方案  1 左侧 div 设置 float 属性为 le ...

  2. 版本控制器之SVN

    1.开发中的实际问题 1.1 小明负责的模块就要完成了,就在即将Release之前的一瞬间,电脑突然蓝屏,硬盘光荣牺牲!几个月来的努力付之东流——需求之一:备份! 1.2 这个项目中需要一个很复杂的功 ...

  3. hdu 4628 Pieces 状态压缩dp

    Pieces Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total S ...

  4. jxls实现基于excel模板的报表

    此文章是基于 搭建Jquery+SpringMVC+Spring+Hibernate+MySQL平台 一. jar包介绍 1. commons-collections-3.2.jar 2. commo ...

  5. Java泛型拾遗

    先上百度百科的解释 泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数.这种参数类型可以用在类.接口和方法的创建中,分别称为泛型类.泛型接口.泛型方 ...

  6. H5安卓端浏览器如何去除select的边框?

    H5安卓端浏览器如何去除select的边框? android下没有问题,在apple下无三角号. -webkit-appearance:none; border-radius:0

  7. php动态链接扩展库

    文章来源:http://keping.me/php-call-so/ PHP调用C/C++动态链接库 David June 19, 2013 C++, Linux, Study 摘要 有时候,单纯依靠 ...

  8. 解决PUTTY出现中文乱码问题

    Putty在默认情况下没有使用UTF-8编码,因此在显示中文的时候会出现乱码.解决方法非常简单:按照下图,在连接之前,左边窗口中的“转换”选项卡(如图所示),然后在右边“假定接收的数据字符集”的下拉选 ...

  9. 基于Docker搭建GitLab服务器

    运行环境:CentOS 7.4 一.安装Docker Docker安装可以参照runoob教程(http://www.runoob.com/docker/centos-docker-install.h ...

  10. maoaolianxi

    package dududu; public class maopao { public static void main(String[] args) { // TODO 自动生成的方法存根 ,,, ...