zoukankan      html  css  js  c++  java
  • HL AsySocket 服务开发框架

    一 概述

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

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

    image

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

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

    二 设计

    那我们有应该如果来设计业务逻辑层呢,尽量与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;
                }
            }
        }

    image

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

    image

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

    四 开发人员

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

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

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

    4:运行HLAsySocketServer启动服务。

    image

  • 相关阅读:
    linux 运维
    mariadb replication
    phpmyadmin
    Objective-C设计模式——单例Singleton(对象创建)
    收藏iOS学习资料
    axios拦截器
    vue单页面优化
    html设置http缓存代码
    js数组去重,排序的几种方法
    前端移动端问题
  • 原文地址:https://www.cnblogs.com/luomingui/p/3191025.html
Copyright © 2011-2022 走看看