那些不好的Socket服务器设计

基础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会话,如下图

那些不好的Socket服务器设计

现在解决刚才的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

上一篇:DP:Apple Catching(POJ 2385)


下一篇:HTML5 文件域+FileReader 分段读取文件并上传到服务器(六)