• 那些不好的Socket服务器设计


    基础Socket 

    自强的程序猿们都喜欢搞Socket,而且觉得最好自己来封装个组件出来,如果再往上,加入某种数据协议,让上层服务器开发照着此协议走,就是一个小小的框架了。于是,从头开始,最开始的服务器的雏形与下图有一些相似。

    现在服务器可以通过socket1到n,分别发送二进制数据到达对应的client1到n了,如果服务器的设计到此打住,本文也就到此打住了,但这个的服务器,毕竟离实际可以拿来作某种服务太遥远了,就于就有了更深层次的封装和扩展。

    两种封装和扩展

    第一种:保留Socket1到n不变,扩展ListenerServer

    例如,现在有一个需求,要服务器发到客户端的数据内容为某些对象序列化后的JSON文本UTF8转码后的二进制,通过继承ListenerServer,我们可以封装一个SendJson的方法

        public class JsonServer : ListenerServer
        {
            public void SendJson(Socket socket, object model)
            {
                var javaScriptSerializer = new System.Web.Script.Serialization.JavaScriptSerializer();
                var json = javaScriptSerializer.Serialize(model);
                this.SendJson(socket, json);
            }
    
            public void SendJson(Socket socket, string json)
            {
                var buffer = Encoding.UTF8.GetBytes(json);
                socket.Send(buffer);
            }
        }

    到此,这种设计感觉依然”完美“,如果往上抽象一层,加入某种协议,基础的ListenerServer的就设计为ListenerServerBase<T> where T:IProtocol,IProtocol形成协议约束。

    让我说,我觉得这种设计基本能解决问题,但职责不单一,会造成上层通讯相关代码和业务服务API代码会偶合在一起,无法分离,因为所有返回数据流,都深深依赖于ListenerServer这个对象。假设ListenerServer为IIS,socket1到n为HttpContext,那么我们的业务API代码就依赖于IIS而不是依赖于HttpContext了,但写了这么多年Asp.net程序,没有人能引用IIS程序集,调用IIS.Instance.Response.Write("这是服务器回复的内容“)如此的代码吧!


    第二种

    ListenerServer只作监听,而socket1到n作类似HttpContext一样封装,在此且命名为Session会话,如下图 

    现在解决刚才的JSON需求的SendJson的方法如下:

        public class JsonSession : Session
        {
            public void SendJson(object model)
            {
                var javaScriptSerializer = new System.Web.Script.Serialization.JavaScriptSerializer();
                var json = javaScriptSerializer.Serialize(model);
                this.SendJson(json);
            }
    
            public void SendJson(string json)
            {
                var buffer = Encoding.UTF8.GetBytes(json);
                base.Send(buffer);
            }
        }

    到这里,感觉逻辑通顺多了,得到一个session会话实例,就可以调用session.SendJson(json)了,不依赖于ListenerServer。而基础ListenerServer可以设计为ListenerServer<T> where T:Session,加入的协议在Session的派生类完成。

    本文只代码作者观点,如果你想继续深入第二种扩展方法,可以参考我的一个socket组件:NetworkSocket

  • 相关阅读:
    Labshare 生物信息学在线软件集锦
    为什么要给单个细胞测序?
    两行代码解决Android9.0 CLEARTEXT communication not supported: [ConnectionSpec...
    Android 网络框架:Retrofit2一篇就够了(2020-4-23)
    Android通用流行框架大全
    base64图片裁剪空白区域
    常用的几款抓包工具
    Message: 'chromedriver' executable needs to be in PATH
    nginx+lua+redis做访问鉴权
    win10安装markdownpad2打开显示错误this view has crashed!
  • 原文地址:https://www.cnblogs.com/kewei/p/4465632.html
Copyright © 2020-2023  润新知