golang tcp heartbeat

leonpengweicn · · 2659 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

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, cS2R, cR2S, 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, cS2R, cR2S, cQuit)
	go Receiver(cTCP, cS2R, cR2S, cQuit)

	<-cQuit
	<-cQuit
}


有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:leonpengweicn

查看原文:golang tcp heartbeat

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

2659 次点击  
加入收藏 微博
0 回复
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传