link包是一个网络层框架,主要面向长连接分包型协议的应用场景。
link包由几个主要部件组成:
这个文件中存放的是link包主要的接口,link包通过这些接口来解耦协议实现和消息包格式。
这个文件中存放的是服务器相关的代码,每个服务器有各自的协议设置等。
这个文件中存放的是会话相关的代码,每个连接在link包中用一个Session表示,每个Session可以有一个自定义的SessionState。
在link中,协议封包和解包、消息的编码和解析都是以buffer为单位进行的,buffer的作用是尽量的减少io操作和内存拷贝。
在link中的每个Session都会有一收一发两个Buffer对象,每次消息收发时会被重用,用于减少内存分配次数。
在实现消息解析的时候需要留意,不要将Buffer对象的Data引用到解析过程之外继续使用(比如对Data进行Slice引用),因为Buffer可能被下一个消息使用,从而导致难以排查的脏数据问题。
link包通过实现内存池来降低内存分配频率,从而进一步提高网络层的效率。
内存池将内存块按大小分成N类,类之间大小差距为1024字节,内存池中对象数量逐级递增,从而实现小对象多,大对象少的缓存布局。
link包中内置了广播的实现,通过实现广播发送器(Boradcaster)所需的Session遍历回调,可以向任何Session集合进行广播发送。
内置的广播发送过程只产生一个Buffer并只编码一次消息,所以效率会优于自己遍历Session逐个发送消息。
但是反过来,在实现自定义协议的时候要留意一个广播用的Buffer可能被并发的使用。
通过将Server和内置的协议实现组合起来,只要实现Decoder接口和Message接口,就可以快速实现一个网络层。
也可以通过实现Protocol和Codec接口来做到自定义封包协议的支持。
在使用中,Server.Serve的回调函数在每个Session创建时会被放在一个独立的goroutine中被调用。所以建议在Server.Serve的回调函数开始时初始化每个Session的State。