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 ...
随机推荐
- MySQL 菜鸟入门“秘籍”
一.MySQL简介 1.什么是数据库 ? 数据库(Database)是按照数据结构来组织.存储和管理数据的仓库,它产生于距今六十多年前,随着信息技术和市场的发展,特别是二十世纪九十年代以后,数据管理不 ...
- 【基础】CSS实现多重边框的5种方式
简言 目前最优雅地实现多重边框的方案是利用CSS3 的 box-shadow属性,但如果要兼容老的浏览器,则需要选择其它的方案.本文简要地列举了几种多重边框的实现方案,大家可以根据项目实际及兼容性要求 ...
- javascript学习笔记(四) Number 数字类型
数字格式化方法toFixed().toExponential().toPrecision(),三个方法都四舍五入 toFixed() 方法指定小数位个数 toExponential() 方法 用科学 ...
- 在Redis Sentinel环境下,jedis该如何配置
在Redis主从复制架构中,如果master出现了故障,则需要人工将slave提升为master,同时,通知应用侧更新master的地址.这样方式比较低效,对应用侧影响较大. 为了解决这个问题,Red ...
- Spring,@Controller,@RequestMapping, @ResponseBody,@RequestParam
1.@Controller,放在类的上方,使类生效; 2.@RequestMapping,,指定一个映射,method为访问方式,headers为含有指定请求头 3. @ResponseBody将返回 ...
- Collections模块下的Counter
class Counter(dict) 这个类是dict的子类,对哈希类型的项进行计数,元素被存储为字典的键,他们的计数将作为字典的键值. 主要介绍两个方法: 1.初始化方法:__init__(*ar ...
- 几大时尚前端UI框架的IE支持
这个文章的Topic比较符合我们这些身在Stone Age用户环境中的开发者所考虑的因素 1.先说目前最火最酷的:Semantic-UI 目前版本:0.17.0 Browser Support Las ...
- AWS技术会议笔记
Intel和云: SDI:软件定义架构 3D-XPointer:可以媲美内存速度的SSD 应用可以控制L3 Cache的使用 Helix物联网设备用 精益创业之路: 如何快速获得第一批用户---先要养 ...
- CSS的display:table
好久都没有写博客了,似乎总是觉得少了些什么-- 刚好最近在工作中遇到了一个新的东西display:table,这个也是css的布局的一种,而且又是display的,之前已经写过了display的fle ...
- JAVA 语法2
1.算术运算符 运算符 运算规则 范例 结果 + 正号 +3 3 + 加 2+3 5 + 连接字符串 "中"+"国" "中国" - 负号 i ...