golang tcp heartbeat

前端之家收集整理的这篇文章主要介绍了golang tcp heartbeat前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
package main

import "log"
import "time"

const TIMEOUT_NS = int64(30e9) // 30 seconds

type Msg struct {
	Header uint8 // == 1
	SeqNo  uint32
	Data   uint8 // the real case is complex
}
type Reply struct {
	Header uint8 // == 2
	SeqNo  uint32
	Status uint8
}
type AskHeartBeat struct {
	Header uint8 // == 4
	SeqNo  uint32
}
type ReplyHeartBeat struct {
	Header uint8 // == 4
	SeqNo  uint32
}
type TCPCh chan interface{} // simulate TCP
type CmdCh chan uint8       // 0:Quit 1:ask HB

var gLastHBTime int64 // heartbeat time

func Sender(tcp TCPCh,cS2R,cR2S,cQuit CmdCh) {
	var cmd uint8
	seq := uint32(1)
	n := 10 // send 10 msgs

L_LOOP:
	for {
		select {
		case cmd = <-cR2S:
			if cmd == 0 {
				break L_LOOP
			}
			if cmd == 1 {
				gLastHBTime = time.Nanoseconds()
				hbr := ReplyHeartBeat{5,seq}
				seq++
				log.Println("S",hbr)
				tcp <- hbr
			}
		default:
			now := time.Nanoseconds()
			if now-gLastHBTime > TIMEOUT_NS {
				hb := &AskHeartBeat{4,seq}
				log.Println("S",hb)
				tcp <- hb
				seq++
			}
			gLastHBTime = now
			if n < 0 {
				time.Sleep(20e9) // wait reply
				cS2R <- 0        // ask to quit
				break L_LOOP
			}
			n--
			m := &Msg{1,seq,0}
			seq++
			log.Println("S",m)
			tcp <- m
		}
	}
	cQuit <- 0
}
func Receiver(tcp TCPCh,cQuit CmdCh) {
	var v interface{}
	var cmd uint8

	lastSeq := uint32(0)

L_LOOP:
	for {
		select {
		case v = <-tcp:
			gLastHBTime = time.Nanoseconds()
			switch v.(type) {
			case Reply:
				r := v.(Reply)
				if lastSeq+1 != r.SeqNo {
					cR2S <- 0 // force sender quit
				}
				log.Println("R",r)
			case AskHeartBeat:
				r := v.(AskHeartBeat)
				if lastSeq+1 != r.SeqNo {
					cR2S <- 0 // force sender quit
				}
				log.Println("R",r)
				cR2S <- 1 // request send ReplyHeartBeat
			case ReplyHeartBeat:
				r := v.(ReplyHeartBeat)
				if lastSeq+1 != r.SeqNo {
					cR2S <- 1 // force sender quit
				}
				log.Println("R",r)
			}
		case cmd = <-cS2R:
			if cmd == 0 {
				break L_LOOP
			}
		}
	}
	cQuit <- 0
}
func main() {
	cTCP := make(chan interface{},1024)
	cQuit := make(chan uint8,2)
	cS2R := make(chan uint8)
	cR2S := make(chan uint8)
	gLastHBTime = time.Nanoseconds()

	go Sender(cTCP,cQuit)
	go Receiver(cTCP,cQuit)

	<-cQuit
	<-cQuit
}

猜你在找的Go相关文章