func (self *HeartbeatHandler) keepAlive() { for { select { case <-time.After(self.heartbeatPeriod): //心跳检测 func() { id := time.Now().Unix() clients := self.clientMangager.ClientsClone() p := protocol.MarshalHeartbeatPacket(id) for h, c := range clients { i := 0 //关闭的时候发起重连 if c.IsClosed() { i = 3 } else { //如果是空闲的则发起心跳 if c.Idle() { for ; i < 3; i++ { hp := packet.NewPacket(protocol.CMD_HEARTBEAT, p) err := c.Ping(hp, time.Duration(self.heartbeatTimeout)) //如果有错误则需要记录 if nil != err { log.Warn("HeartbeatHandler|KeepAlive|FAIL|%s|local:%s|remote:%s|%d\n", err, c.LocalAddr(), h, id) continue } else { log.Info("HeartbeatHandler|KeepAlive|SUCC|local:%s|remote:%s|%d|%d ...\n", c.LocalAddr(), h, id, i) break } } } } if i >= 3 { //说明连接有问题需要重连 c.Shutdown() self.clientMangager.SubmitReconnect(c) log.Warn("HeartbeatHandler|SubmitReconnect|%s\n", c.RemoteAddr()) } } }() } } }
func (self *HeartbeatHandler) Process(ctx *DefaultPipelineContext, event IEvent) error { hevent, ok := self.cast(event) if !ok { return ERROR_INVALID_EVENT_TYPE } //处理本地的pong hevent.RemoteClient.Pong(hevent.Opaque, hevent.Version) //发起一个ping对应的响应 packet := packet.NewRespPacket(hevent.Opaque, protocol.CMD_HEARTBEAT, protocol.MarshalHeartbeatPacket(hevent.Version)) //发起一个网络请求 remoteEvent := NewRemotingEvent(packet, []string{hevent.RemoteClient.RemoteAddr()}) // log.InfoLog("kite_handler", "HeartbeatHandler|%s|Process|Recieve|Ping|%s|%d\n", self.GetName(), hevent.RemoteClient.RemoteAddr(), hevent.Version) ctx.SendForward(remoteEvent) return nil }