框架概述
EzHttp是临时起意构思和开发的一个框架,目的在于简化CS轻应用开发过程。开发语言是C#。
普通的基于HTTP的应用开发基本上是RESTful的,客户端调用封装需要人工写代码,就算利用三方库,是不是也要填写一个相对路径。
以前的webservice倒是通过引用的方式编译的时候可以自动生成客户端调用,但服务器必须在线的时候才能更新。
为什么我们不能创建一种优雅的调用方式,比如基于约定的接口。并且这个接口就是C#语言中的interface而不是指一个url地址。
服务端和客户端引用接口DLL共享接口信息,通过一个中间框架在客户端和服务器之间构建Http请求和应答。基于此构想,EzHttp项目诞生。
框架使用
设想这样一个例子,
1、有三个项目,分别是服务端,客户端,接口。
2、服务端引用接口项目并实现接口方法。
3、客户端引用接口并通过EzHttp框架的客户端对象获取一个接口的代理对象。
现在,客户端可以通过接口调用方法获取返回的值。这个值就服务端对接口方法实现的类的那个方法返回的值。
于是客户端开发终于如webservice生成引用代理后一般清爽,并且共享接口可以同步更新。
设计思路
通过框架创建客户端代理对象,封装客户端调用为HTTP调用并将返回值做适当处理提供给方法返回值。
框架实现基础是基于已生成的类库中的对象都有唯一的ID。
过程如下:
1、在初始化客户端的调用之前,从服务端获取元数据(包含接口和实现的类型ID映射)。
2、服务端通过反射获取和缓存元数据并返回给客户端。
3、客户端调用接口方法时,框架通过Http封装方法元数据和实参提交给服务器。
4、服务端解析后找到接口实现类,实例化后执行对应的方法,获取返回值后写入Http应答。
5、客户端解析应答和处理调用错误。
高级支持
接口支持设计返回值为Task或Task<T>的方法
提供一个用于传输流的接口,客户端可使用该接口从服务端返回文件等流数据。
为什么提供单独的流传输接口而不使用返回值为byte[]的普通接口方法?
当流长度较大时,普通接口的byte[]数据会完全进入内存,消耗服务器资源。
而独立设计的流传输接口使用缓冲区读写数据。避免了由于流数据过大程序无法处理造成的崩溃或服务器负荷急剧增加。
开发路线图
支持接口依赖注入
支持用于接口实现和接口方法实现的拦截器(筛选器)
代码预览
服务端
EzHttp.EzServer server = new EzHttp.EzServer(); server.Start($"http://127.0.01:8000/");
接口:
public interface ITranslateApi { /// <summary> /// 翻译(英译中) /// </summary> /// <param name="input"></param> /// <returns></returns> string Translate(string input); /// <summary> /// 翻译(英译中)并提取关键词 /// </summary> /// <param name="input"></param> /// <param name="count"></param> /// <param name="weightOut"></param> /// <returns></returns> string TranslateAndGetKeywords(string input, int count, bool weightOut); }
接口实现:
public class TranslateImpl : EzHttp.EzHandler, ITranslateApi { public string Translate(string input) { if (string.IsNullOrEmpty(input)) { throw new Exception("input can not be null"); } return Form1.Instance.Translate(input); } public string TranslateAndGetKeywords(string input, int count, bool weightOut) { if (string.IsNullOrEmpty(input)) { throw new Exception("input can not be null"); } var output = Translate(input); if (string.IsNullOrEmpty(output)) { throw new Exception("translate result is null."); } if (!KeyWordExtract.NLPIR_Init(@".\", 0))//给出Data文件所在的路径,注意根据实际情况修改。 { throw new Exception("keyword extraction service init error"); } var ptr = KeyWordExtract.NLPIR_GetKeyWords(output, count, weightOut); return Marshal.PtrToStringAnsi(ptr); } }
客户端调用
EzClient.Initialize("http://127.0.0.1:8000/"); var api = EzClient.ProxyFactory.GetProxy<ITranslateApi>(); api.Translate(System.IO.File.ReadAllText("input.txt"));
参与框架讨论:590883722
框架下载:下载EzHttp