一 概述

Socket服务只是提供一个网络传输服务。

业务逻辑层在整体架构中的位置在那里呢,如图:

网络层将解包后的消息包抛至业务逻辑层,业务逻辑层收到消息包后,解析消息类型,然后转入相应的处理流程处理

网络层应提供发送消息的接口供业务逻辑层调用,因为网络层不会主动发送消息,发送消息的操作是由业务逻辑层来控制的,所以业务逻辑层应根据具体的业务应用,封装不同功能的发送消息的方法。

二 设计

那我们有应该如果来设计业务逻辑层呢,尽量与Socket解耦合以达到相对的独立性。

根据上面的图来说是根据业务类型来处理不同的业务逻辑,并返回给客服端提示结果。

我们先来设计一个通用的业务接口,如下:

public interface ICommand<T>
{
      void Execute(T session, CommandInfo commandData);

}

代码解释:

session 对象主要包含如下功能:发送数据给客服端,会话验证,

commandData 对象主要包含业务Type处理业务。

函数体:主要就是根据commandData业务类型,转发到业务逻辑层处理业务并返回结果,有session发送给客服端。

流程:

1:Socket服务启动的时候把事先设定好的业务Type数据加载到内存。

2:Socket通过监听客服端连接,并接受数据的时候时,通过客服端传过来的业务Type来查找服务上的业务Type集合。

3:如果存在就转发到业务逻辑层处理业务并返回结果,有session发送给客服端。不存在直接返回并告知客服端服务器上没有此服务,请联系开发商。

性能瓶颈:

1:如果网络层和业务层在同一个线程中,那么网络层的处理必须等待数据库执行完毕后,才能进行!如果数据库执行效率比较慢,那对整个socket服务器将是一个毁灭性的打击。

三 具体实现

根据上面所说,网络层应该和业务逻辑层分开执行,并加入超时时间,时间一到不关结果如何,都将返回。

第一步:Socket服务启动的时候把事先设定好的业务Type数据加载到内存.

 public partial class HLEnvironment
{
private static Dictionary<string, ICommand<AsyncSocketSession>> dictCommand = new Dictionary<string, ICommand<AsyncSocketSession>>(StringComparer.OrdinalIgnoreCase);
public static void LoadCommands( )
{
Type commandType = typeof(ICommand<AsyncSocketSession>);
Assembly asm = typeof(AsyncSocketSession).Assembly;
Type[] arrType = asm.GetExportedTypes(); for (int i = 0; i < arrType.Length; i++)
{
var commandInterface = arrType[i].GetInterfaces().SingleOrDefault(x => x == commandType); if (commandInterface != null)
{
dictCommand[arrType[i].Name] = arrType[i].GetConstructor(new Type[0]).Invoke(new object[0]) as ICommand<AsyncSocketSession>;
}
}
Stup();
}
private static void Stup( )
{
Type commandType = typeof(ICommand<AsyncSocketSession>);
var files = EnumerateAllLibFiles();
foreach (var file in files)
{
Assembly ass = Assembly.LoadFrom(file);
Type[] arrType = ass.GetExportedTypes(); for (int i = 0; i < arrType.Length; i++)
{
var commandInterface = arrType[i].GetInterfaces().SingleOrDefault(x => x == commandType);
if (commandInterface != null)
{
dictCommand[arrType[i].Name] = arrType[i].GetConstructor(new Type[0]).Invoke(new object[0]) as ICommand<AsyncSocketSession>;
}
}
}
}
public static ICommand<AsyncSocketSession> GetCommandByName(string commandName)
{
ICommand<AsyncSocketSession> command; if (dictCommand.TryGetValue(commandName, out command))
return command;
else
return null;
}
public static IEnumerable<string> EnumerateAllLibFiles()
{
string libraryPath = MapDllPath("Servers\\");
Directory.CreateDirectory(libraryPath);
foreach (var dll in Directory.GetFiles(libraryPath, "*.dll"))
{
yield return dll;
}
}
}

第二步:Socket通过监听客服端连接,并接受数据的时候时,通过客服端传过来的业务Type来查找服务上的业务Type集合。

  protected override void ExecuteCommand(SocketSendData cmdInfo)
{
ICommand<AsyncSocketSession> command = HLEnvironment.GetCommandByName(cmdInfo.SocketCommandName);
if (command != null)
{
command.ExecuteCommand(this, cmdInfo);
}
}
3:如果存在就转发到业务逻辑层处理业务并返回结果,有session发送给客服端。不存在直接返回并告知客服端服务器上没有此服务,请联系开发商。
业务逻辑与Socket服务衔接的地方

四 开发人员

1:新建一个业务逻辑层,编写业务逻辑。

2:新建一个业务服务层,主要实现ICommand接口。

3:把开发好的Dll放到Servers文件夹下。

4:运行HLAsySocketServer启动服务。

最新文章

  1. [Erlang 0126] 我们读过的Erlang论文
  2. java 中List.subList 总结
  3. 微信小程序(应用号)开发资源汇总整理 - 一直更新中
  4. MapReduce实例-倒排索引
  5. elasticsearch的marvel
  6. css 字数超过一行显示省略号
  7. hibernate主键生成机制与save返回
  8. UX结合需求实例化进行设计开发
  9. 在XML里的XSD和DTD以及standalone的使用3----具体使用详解
  10. UVa 753 (二分图最大匹配) A Plug for UNIX
  11. iOS: 学习笔记, Swift与Objective-C混用简明教程(转载)
  12. SVN:冲突解决 合并别人的修改
  13. vim插件管理之Vundle
  14. Python 由__dict__和dir()引发的一些思考
  15. jQuery 实现无限任意添加下拉菜单
  16. C++并发高级接口:std::async和std::future
  17. 页面加载完之前显示Loading
  18. AspNetCore.FileLog 一款很不错的日志记录工具
  19. DNS搭建
  20. Markdown语法参考

热门文章

  1. JSONP跨域数据调用
  2. PHP会话Session
  3. 个性二维码开源专题&lt;后背景&gt;
  4. 更改MySql表和字段区分大小写
  5. [安卓] 3、EditText使用小程序
  6. 由Java中toString()方法引发的无意识的递归想到的
  7. JavaScript text highlighting JQuery plugin
  8. Django站点管理--ModelAdmin
  9. C#与数据库访问技术总结(八)之ExecuteNonQuery方法
  10. iOS Runtime原理及使用