LayIM.AspNetCore Middleware 开发日记(五)Init接口实现细节
前言
“一旦开始了就要坚持下去“。为什么本文的第一句话是这么一句话呢,因为我经常就是开头轰轰烈烈,结果越来越枯燥,就不想做下去了。但是版图就放弃又那么不甘心,继续加油吧。
吐槽完毕,进入正题。在上一篇中我们的主角LayIM已经登场了。而且界面已经实现,那么有些小伙伴就有疑惑了,详细流程是什么样的,今天我就介绍一个东西,那就是 /layim/init 接口的实现细节
另外,项目已经升级至 .NET CORE 2.1 ,最新代码在 dev-netcore2.1 分支上
需求
需求是什么?需求是将LayIM的主界面显示出来。如下:

嗯,就是这么个东西。在上一篇中我已经介绍到,init接口就是为了实现主界面的,那么主界面的数据是什么样的呢?(其实在两年前的博客中已经讲过,这里在稍微提一下)我们看一下DEMO中的getList.json.

如上图,我们只要定义一个接口然后输出上图格式中的json数据即可。由于我在框架中用SQLServer给了一个默认实现,关系型数据库那肯定是各种关系啦。首先定义最基本的表。
用户表,用户好友分组表,用户好友关系表,群组表,群组群员关系表。目前这五个表足够了。
下面逐个分析击破:
mine:当前用户信息,从用户表取出即可
friend:首先从用户好友分组表取出当前用户所有的分组,在从用户好友关系表取出好友。然后程序中去匹配该好友对应的分组即可。及分组和好友是一对多的关系
group:从群组群员关系表中取出当前用户所在的群,然后在从群组表取出相应的群信息,组合数据即可
具体代码实现
下面的代码如果有不理解的地方,可以先从前面几篇中补补课。
首先,毋庸置疑,先将路由配置上:
routes.AddQuery("/init", async context => await GetInitData(context));
GetInitData 做了什么事呢?它就是获取注册的 ILayIMStorage 实例,然后调用接口方法获取数据。
public interface ILayIMStorage
{
/// <summary>
/// 初始化数据
/// </summary>
/// <param name="userId"></param>
/// <returns></returns>
Task<LayIMInitModel> GetInitData(string userId); /// <summary>
/// 保存聊天记录
/// </summary>
/// <param name="message"></param>
/// <returns></returns>
Task<int> SaveMessage(LayIMMessageModel message);
}
接口实现类
在项目 LayIM.AspNetCore.Storage.SqlServer中实现ILayIMStorage接口.Repository具体代码就不在粘贴了,就是一系列Sql的查询然后数据组合。
/// <summary>
/// 获取初始化数据
/// </summary>
/// <param name="userId"></param>
/// <returns></returns>
public async Task<LayIMInitModel> GetInitData(string userId)
{
var mineTsk = userRepository.GetUserById(userId);
var friendGroupsTask = friendGroupRepository.GetUserGroups(userId);
var friendRelationsTask = friendRelationRepository.GetFriendRelations(userId);
var groupIdsTask = groupMemberRepository.GetUserBigGroups(userId); LayIMInitModel initModel = new LayIMInitModel
{
//用户自己
mine = await mineTsk
};
//好友列表
List<FriendGroupModel> friend = new List<FriendGroupModel>(); IEnumerable<FriendGroupModel> friendGroups = await friendGroupsTask;
IEnumerable<FriendRelationShip> friendRelations = await friendRelationsTask;
IEnumerable<long> friendIds = friendRelations.Select(x => x.FriendId); IEnumerable<UserModel> friends = await userRepository.GetUsersByIds(friendIds); if (friendIds?.Count() > )
{
foreach (var group in friendGroups)
{
var friendIdsInGroup = friendRelations.Where(r => r.GroupId == group.id).Select(r => r.FriendId); group.list = friends.Where(x => friendIdsInGroup.Any(f => f == x.id));
}
} friend.AddRange(friendGroups); initModel.friend = friend; //群组列表
IEnumerable<long> groupIds = await groupIdsTask;
var bigGroupsTask = bigGroupRepository.GetBigGroups(groupIds);
initModel.group = await bigGroupsTask; return initModel;
}
写完方法之后,记得要注册服务。
/// <summary>
/// 使用SqlServer
/// </summary>
/// <param name="services"></param>
/// <param name="setConfig"></param>
public static IServiceCollection AddSqlServer(this IServiceCollection services,string connectionString)
{
var dbConfig = new DBConnectionConfig(DBType.SqlServer)
{
ConnectionString = connectionString
};
services.AddSingleton(dbConfig);
services.AddSingleton<ILayIMStorage, LayIMDapperStorage>();
return services;
}
然后在Demo中的使用方法如下:
services.AddLayIM().AddRongCloud(config =>
{
config.AppKey = "appkey";
config.AppSecret = "appsecret";
})
.AddSqlServer("connectionString");
重启项目,测试一下 layim/init 接口。数据返回正常

当然,一个好友的用户数据一般变化不大,所以对于接口要增加缓存设计。不过这里我暂时没有实现,只是先临时用了 IMemoryCache。
请求回放
首先,由于请求的 Path 是 /layim 开头的,所以中间件判定为LayIM请求,然后在经过路由转发器,找到对应的处理器。
var dispatcher = LayIMRoutes.Routes.FindDispatcher(path);
之前已经介绍过,Dispatcher 是实现了Dispatch 方法的。
internal interface ILayIMDispatcher
{
Task Dispatch(HttpContext context);
}
所以,最终的请求其实都会落到路由注册的方法中,也就是上文中的 routes.AddQuery("/init", async context => await GetInitData(context)); 那么其他的返回ContentType,转JSON就是框架实现了,业务没必要关心它了。
说到这里可能大家还是比较迷糊,下面是一个Dispatcher之间的关系图.

MethodFilterDispatcher 抽象类 负责请求方法的校验。GET POST PUT DELETE 等
CommandDispatcher<TResult> 抽象类 负责主业务逻辑处理,模板方法,处理细节交给实现类
ExecuteCommandDispatcher<TResult> 实现类,POST请求
QueryCommandDispatcher<TResult> 实现类,GET 请求
其他待扩展
总结
本文通过一个 /layim/init 接口的详细介绍,通过这个接口请求流程,大家能够对框架的处理部分设计有所理解。另外,本文内容都是在后端,至于前台怎么绑定数据处理等,咱们下回分解。
博客预告:LayIM.AspNetCore Middleware 开发日记(六)嵌入资源的使用,layim.config的封装
项目地址:https://github.com/fanpan26/LayIM.AspNetCore 欢迎小伙伴们star 围观 提意见。
LayIM.AspNetCore Middleware 开发日记(五)Init接口实现细节的更多相关文章
- LayIM.AspNetCore Middleware 开发日记(一)闲言碎语
前言 前几天写博客的时候突然看见了历史上的今天.不禁感慨时光如梭,这系列博客后来被我标注了已经过时,但是还有很多小伙伴咨询我.既然过时就要更新,正好 .NET Core 也出来很久了,于是乎想到把La ...
- LayIM.AspNetCore Middleware 开发日记(四)主角登场(LayIM介绍)
前言 在前几篇中已经初步介绍了开发AspNetCore中间件的一些基础知识,不过都没有很深入的去研究,后续还是需要去看看源码.本篇呢,终于有点开头的味道了,就是要介绍LayIM了,其实标题写的是主角, ...
- LayIM.AspNetCore Middleware 开发日记(三)基础框架搭建
前言 在上一篇中简单讲了一些基础知识,例如Asp.Net Core Middleware 的使用,DI的简单使用以及嵌入式资源的使用方法等.本篇就是结合基础知识来构建一个基础框架出来. 那么框架有什么 ...
- LayIM.AspNetCore Middleware 开发日记(六)嵌入资源的使用,layim.config的封装
前言 距离上一篇博客竟然已经10多天了...工作上的事,个人原因,种种吧.不多说废话,本文将会重点介绍layim的入口配置. LayIM配置 其实在开发者文档里面已经描述的很清楚了.除了几个重要的接口 ...
- LayIM.AspNetCore Middleware 开发日记(二)预备知识介绍
前言 开发一个AspNetCore的中间件需要理解RequestDelegate.另外,还需要理解.NET Core中的依赖注入.还有一个就是内嵌资源的访问.例如:EmbeddedFileProvid ...
- LayIM.AspNetCore Middleware 开发日记(七)Asp.Net.Core.SignalR闪亮登场
前言 前几篇介绍了整个中间件的构成,路由,基本配置等等.基本上没有涉及到通讯部分.不过已经实现了融云的通讯功能,由于是第三方的就不在单独去写.正好.NET Core SignalR已经出来好久了, ...
- 【Android开发日记】之入门篇(五)——Android四大组件之Service
这几天忙着驾校考试,连电脑都碰不到了,今天总算告一段落了~~Service作为Android的服务组件,默默地在后台为整个程序服务,辅助应用与系统中的其他组件或系统服务进行沟通.它跟Activity的 ...
- 五、利用EnterpriseFrameWork快速开发基于WebServices的接口
回<[开源]EnterpriseFrameWork框架系列文章索引> EnterpriseFrameWork框架实例源代码下载: 实例下载 前面几章已完成EnterpriseFrameWo ...
- 嵌入式Linux驱动开发日记
嵌入式Linux驱动开发日记 主机硬件环境 开发机:虚拟机Ubuntu12.04 内存: 1G 硬盘:80GB 目标板硬件环境 CPU: SP5V210 (开发板:QT210) SDRAM: 512M ...
随机推荐
- Web服务器学习总结(一):web服务器简介
一.WEB服务器 1.1.WEB服务器简介 1.Web服务器是指驻留于因特网上某种类型计算机的程序,是可以向发出请求的浏览器提供文档的程序.当Web浏览器(客户端)连到服务器上并请求文件时,服务器将处 ...
- Ueditor更改编辑框样式
1.在ueditor.all.min.js文件中查找“ueditor.css”,找到位置后更改css文件,或在原文件中更改
- Hadoop、Hive、Spark 之间关系
作者:Xiaoyu Ma ,大数据工程师 大数据本身是个很宽泛的概念,Hadoop生态圈(或者泛生态圈)基本上都是为了处理超过单机尺度的数据处理而诞生的.你可以把它比作一个厨房所以需要的各种工具.锅碗 ...
- 【转】使用expect实现shell自动交互
原文地址:http://www.nginx.cn/1934.html shell脚本需要交互的地方可以使用here文档是实现,但是有些命令却需要用户手动去就交互如passwd.scp 对自动部署免去用 ...
- Windows ->> Windows Server 2012打开管理添加“我的电脑”桌面图标途径
Windows Server 2012打开管理添加“我的电脑”桌面图标途径 rundll32.exe shell32.dll,Control_RunDLL desk.cpl,,0
- c#微信开发,使用JS-SDK自定义分享功能,分享朋友圈,分享给朋友等
如果一个后端开发掌握了微信开发,甚至有微信开发上线项目,这在换工作的时候 还是有竞争力的. 微信开发的资料很多,但是用asp.net c#进行微信开发好像比较少,或者资料不够完整. 使用JS-SDK自 ...
- 安装Xcode主题
安装Xcode主题 下载地址 https://github.com/YouXianMing/Xcode-Themes 安装教程 1. 安装文件夹中的字体 2. 如下图,执行 ./cp_themes.s ...
- 执行系统命令,subprocess使用说明
os.system('ls -l') #只执行命令,不能将结果赋予变量 os.system('mkdir test') #创建test目录 files = os.popen('ls -l').rea ...
- matlab中的knn函数
knn 最邻近分类 Class = knnclassify(test_data,train_data,train_label, k, distance, rule) k:选择最邻近的数量 distan ...
- miniblast_hash算法c语言实现
对于一组基因文件中的基因序列,选取一段基因片段,作为索引,利用hash表,查找固定的基因片段.有一定的并且容忍错误. 简单讲就是自己实现一个hashtable,将选出特定字符串建立索引,便于查询.输出 ...