go语言nsq源码解读六 tcp.go、tcp_server.go
本篇讲nsqlookupd中tcp.go、tcp_server.go
tcp_server.go位于util目录下。
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
package util
import ( "log" "net" "runtime" "strings" ) type TCPHandler interface { Handle(net.Conn) } /** *本方法开始接受客户端连接,并注册处理方法 */ func TCPServer(listener net.Listener, handler TCPHandler) { log.Printf("TCP: listening on %s", listener.Addr().String()) for { clientConn, err := listener.Accept() if err != nil { if nerr, ok := err.(net.Error); ok && nerr.Temporary() { log.Printf("NOTICE: temporary Accept() failure - %s", err.Error()) runtime.Gosched() continue } // theres no direct way to detect this error because it is not exposed if !strings.Contains(err.Error(), "use of closed network connection") { log.Printf("ERROR: listener.Accept() - %s", err.Error()) } break } //handler由调用时通过参数传入,作为工具方法,将可能的变化放在外部,以保证本方法可以有尽可能多的适用范围 go handler.Handle(clientConn) } log.Printf("TCP: closing %s", listener.Addr().String()) } |
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
package nsqlookupd
import ( "io" "log" "net" "github.com/bitly/nsq/util" ) type tcpServer struct { context *Context } // // nsqlookupd接收到tcp数据时,会调用本方法处理。 //实现了/util/tcp_server.go中定义的TCPHandler接口 // func (p *tcpServer) Handle(clientConn net.Conn) { log.Printf("TCP: new client(%s)", clientConn.RemoteAddr()) // The client should initialize itself by sending a 4 byte sequence indicating // the version of the protocol that it intends to communicate, this will allow us // to gracefully upgrade the protocol away from text/line oriented to whatever... //客户端在初始化自己的时候,需要发送4字节的数据用来标识它自己所有使用协议版本。将来升级协议的时候可以避免使用旧协议的客户端不能使用。 buf := make([]byte, 4) _, err := io.ReadFull(clientConn, buf) if err != nil { log.Printf("ERROR: failed to read protocol version - %s", err.Error()) return } //获取协议内容 protocolMagic := string(buf) log.Printf("CLIENT(%s): desired protocol magic '%s'", clientConn.RemoteAddr(), protocolMagic) //util\Protocol.go中定义了一个Protocol的接口 var prot util.Protocol switch protocolMagic { case " V1": //当前只支持" V1"协议(前两有两个空格,所以总共是4字节),协议在nsqlookupd\lookup_protocol_v1.go文件中定义,这里创建了LookupProtocolV1的实例 //LookupProtocolV1实现了Protocol接口 prot = &LookupProtocolV1{context: p.context} default: //如果不是" V1"协议,则协议出错,断开链接,返回。 util.SendResponse(clientConn, []byte("E_BAD_PROTOCOL")) clientConn.Close() log.Printf("ERROR: client(%s) bad protocol magic '%s'", clientConn.RemoteAddr(), protocolMagic) return } //如果是" V1"f协议,这里就进入了LookupProtocolV1的IOLoop方法。此方法里有for死循环运行,直到出现error时,才会执行下面的代码。 err = prot.IOLoop(clientConn) if err != nil { log.Printf("ERROR: client(%s) - %s", clientConn.RemoteAddr(), err.Error()) return } } |
从以上代码可看出,tcp.go和tcp_server.go主要功能就是监听并接受TCP请求,收到请求后,将数据转给lookup_protocol_v1.go来处理。这个下篇再讲。
go语言nsq源码解读六 tcp.go、tcp_server.go的更多相关文章
- go语言nsq源码解读九 tcp和http中channel、topic的增删
通过前面多篇文章,nsqlookupd基本已经解读完毕了,不过在关于channel和topic的增删上还比较模糊,所以本篇将站在宏观的角度来总结一下,tcp.go和http.go两个文件中关于chan ...
- go语言nsq源码解读八 http.go、http_server.go
这篇讲另两个文件http.go.http_server.go,这两个文件和第六讲go语言nsq源码解读六 tcp.go.tcp_server.go里的两个文件是相对应的.那两个文件用于处理tcp请求, ...
- (转)go语言nsq源码解读二 nsqlookupd、nsqd与nsqadmin
转自:http://www.baiyuxiong.com/?p=886 ---------------------------------------------------------------- ...
- go语言 nsq源码解读三 nsqlookupd源码nsqlookupd.go
从本节开始,将逐步阅读nsq各模块的代码. 读一份代码,我的思路一般是: 1.了解用法,知道了怎么使用,对理解代码有宏观上有很大帮助. 2.了解各大模块的功能特点,同时再想想,如果让自己来实现这些模块 ...
- go语言nsq源码解读七 lookup_protocol_v1.go
本篇将解读nsqlookup处理tcp请求的核心代码文件lookup_protocol_v1.go. 1234567891011121314151617181920212223242526272829 ...
- go语言nsq源码解读二 nsqlookupd、nsqd与nsqadmin
nsqlookupd: 官方文档解释见:http://bitly.github.io/nsq/components/nsqlookupd.html 用官方话来讲是:nsqlookupd管理拓扑信息,客 ...
- go语言nsq源码解读一-基本介绍
简单介绍一下nsq. 参考 http://feilong.me/2013/05/nsq-realtime-message-processing-system 的介绍:NSQ是由知名短链接服务商bitl ...
- go语言 nsq源码解读四 nsqlookupd源码options.go、context.go和wait_group_wrapper.go
本节会解读nsqlookupd.go文件中涉及到的其中三个文件:options.go.context.go和wait_group_wrapper.go. options.go 123456789101 ...
- go语言nsq源码解读五 nsqlookupd源码registration_db.go
本篇将讲解registration_db.go文件. 1234567891011121314151617181920212223242526272829303132333435363738394041 ...
随机推荐
- 杭电ACM 1000题
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner cin=n ...
- eclipse中tomcat内存溢出设置
Eclipse里启动Tomcat,配置内存大小 2009年12月11日 星期五 10:50 一般安装完eclipse之后,在安装目录下你应该可以看到有一个 eclipse.ini 文件,对了,就是在这 ...
- SQL 经典语句
15题需要再分析.没弄懂 使用scott/tiger用户下的emp表和dept表完成下列练习, 表的结构说明如下 emp员工表(empno员工号/ename员工姓名/job工作/mgr上级编号/hir ...
- Lintcode397 Longest Increasing Continuous Subsequence solution 题解
[题目描述] Give an integer array,find the longest increasing continuous subsequence in this array. An in ...
- codechef Chef And Easy Xor Queries
做法:我们考虑前缀异或和,修改操作就变成了区间[i,n]都异或x 查询操作就变成了:区间[1,x]中有几个k 显然的分块,每个块打一个tag标记表示这个块中所有的元素都异或了tag[x] 然后处理出这 ...
- SharePoint2013 功能区的配置
遇到了很多次对网站功能区个性化定义的任务,包括标签按钮之类的修改,每次都要重新翻书,这次总结一下,留作备用. 添加内容 下面的XML我认为主要的内容是四部分,一个是CommandUIDefinitio ...
- Spark核心编程---创建RDD
创建RDD: 1:使用程序中的集合创建RDD,主要用于进行测试,可以在实际部署到集群运行之前,自己使用集合构造测试数据,来测试后面的spark应用流程. 2:使用本地文件创建RDD,主要用于临时性地处 ...
- 蚂蚁 RPC 框架 SOFA-RPC 初体验
前言 最近蚂蚁金服开源了分布式框架 SOFA,楼主写了一个 demo,体验了一下 SOFA 的功能,SOFA 完全兼容 SpringBoot(当然 Dubbo 也是可以兼容的). 项目地址:Alipa ...
- 12.Django思维导图
- Maven Scope 依赖范围
Maven依赖范围就是用来控制依赖与这三种classpath(编译classpath.测试classpath.运行classpath)的关系,Maven有以下几种依赖范围: ·compile:编译依赖 ...