nsq 源码分析之tcp协议部分

    最近刚好看到其他几个项目有socket 编程,然后,想了下,在golang 中还没用过socket tcp 编程,于是看了一些im 的协议解析过程,都不是太满意,不是太通用,刚好看到nsq,发现nsq 这部分真是简单粗暴。还用的是标准库的一些东西,非常通用。

    nsq 的协议文档地址:https://nsq.io/clients/tcp_protocol_spec.html。

    首先,tcp 编程,最麻烦的地方是处理粘包,这个玩意怎么处理,一般是通过分隔符和两次读处理。httppaser 基本会封装这两种,比如tornado 的readbytes,readuntil,一个是定长读,一个是读到某个标识符为止,中间会为读写分配个缓冲区。这里道理很好理解,定长读,先读约定的header,比如先读4个字节,得到后面有n个字节后,一直循环向buffer 放,而readuntil 每次read 放到buffer,不断find 分隔符。这里的边界条件,不管是python 还是c 写起来都是比较麻烦的事情。

    其实golang 里算是比较简单的,看个例子,下面这个是典型,第一行是command,'\n'分隔符结尾,第二行,因为这个command 有参数,用4个字节约定后面body 长度。

Publish a message to a topic:

PUB <topic_name>\n
[ 4-byte size in bytes ][ N-byte binary data ]

<topic_name> - a valid string (optionally having #ephemeral suffix)

    我们做的时候,只需要有两个函数,一个能readuntil,一个能readbytes就ok,golang 有没?其实golang标准库是有的,分别是bufio.ReadSlice ,对应readuntil, 一个是io.ReadFull, 对应readbytes。

    看下bufio.ReadSlice,用法,源码

    看下io.ReadFull,用法,源码

    分析nsq 的tcp server

猜你喜欢

转载自my.oschina.net/u/2950272/blog/1816971
nsq