golang p2p网

Python016

golang p2p网,第1张

继续进入下一个初始化

n.netService, err = nebnet.NewNebService(n)

if err != nil {

logging.CLog().WithFields(logrus.Fields{

"err": err,

}).Fatal("Failed to setup net service.")

}

netservice有两个成员

type NebServicestruct {

node      *Node

dispatcher *Dispatcher

}

跳出stup()函数

先进入start()函数看一看

if err := n.netService.Start()err != nil {

logging.CLog().WithFields(logrus.Fields{

"err": err,

}).Fatal("Failed to start net service.")

}

进入netservice.start()

func (ns *NebService) Start() error {

logging.CLog().Info("Starting NebService...")

// start dispatcher.

  ns.dispatcher.Start()

// start node.

  if err := ns.node.Start()err != nil {

ns.dispatcher.Stop()

logging.CLog().WithFields(logrus.Fields{

"err": err,

}).Error("Failed to start NebService.")

return err

}

logging.CLog().Info("Started NebService.")

return nil

}

可以看到第一个start()的函数是dispatcher.start()

进入dispatch.start()

func (dp *Dispatcher) Start() {

logging.CLog().Info("Starting NebService Dispatcher...")

go dp.loop()

}

然后就出现一个新的线程、goruntime

go dp.loop()

进入该线程,看它干了些什么

timerChan := time.NewTicker(time.Second).C

for {

select {

case <-timerChan:

metricsDispatcherCached.Update(int64(len(dp.receivedMessageCh)))

case <-dp.quitCh:

logging.CLog().Info("Stoped NebService Dispatcher.")

return

  case msg := <-dp.receivedMessageCh:

msgType := msg.MessageType()

v, _ := dp.subscribersMap.Load(msgType)

if v == nil {

continue

      }

m, _ := v.(*sync.Map)

m.Range(func(key, valueinterface{}) bool {

select {

case key.(*Subscriber).msgChan <- msg:

default:

logging.VLog().WithFields(logrus.Fields{

"msgType": msgType,

}).Warn("timeout to dispatch message.")

}

return true

      })

}

}

一个有点长的循环

metricsDispatcherCached.Update(int64(len(dp.receivedMessageCh)))一秒钟刷新一次缓冲区

case msg := <-dp.receivedMessageCh:

msgType := msg.MessageType()如果能取出dp.receivedMessageCh

msgType := msg.MessageType()首先判断取出的信息类型

v, _ := dp.subscribersMap.Load(msgType)

if v == nil {

continue

}

根据类型取出相应的map

如果取不出,那么使用continue结束这个case

m, _ := v.(*sync.Map)

断言

m.Range(func(key, valueinterface{}) bool {

select {

case key.(*Subscriber).msgChan <- msg:

default:

logging.VLog().WithFields(logrus.Fields{

"msgType": msgType,

}).Warn("timeout to dispa+tch message.")

}

return true

})

将msg推入其他管道里面去。其他goruntime会循环等待该

《Go语言实战》(威廉·肯尼迪 (William Kennedy))电子书网盘下载免费在线阅读

链接:https://pan.baidu.com/s/1mNt2bRjwacBu3C5YNe-dOQ

提取码:1234

书名:Go语言实战

作者:威廉·肯尼迪 (William Kennedy)

译者:李兆海

豆瓣评分:7.7

出版社:人民邮电出版社

出版年份:2017-3-1

页数:224

内容简介:

Go语言结合了底层系统语言的能力以及现代语言的高级特性,旨在降低构建简单、可靠、高效软件的门槛。本书向读者提供一个专注、全面且符合语言习惯的视角。Go语言实战同时关注语言的规范和实现,涉及的内容包括语法、类型系统、并发、管道、测试,以及其他一些主题。

作者简介:

William Kennedy,是一位熟练的软件开发者,也是博客GoingGo.Net的作者。

Brian Ketelsen和Erik St. Martin是全球Go语言大会GopherCon的组织者,也是Go语言框架Skynet的联合作者。

李兆海,多年专注于后端分布式网络服务开发,曾使用过多个流行后端技术和相关架构实践,是Go语言和Docker的早期使用者和推广者,《第1本Docker书》的译者。作为项目技术负责人,成功开发了百万用户级直播系统。

据我所知道,目前流行的语言大部分是java,c+,c语言,php,当然别的语言也可以,比如go,Python语言都是很不错的语言,要看哪个语言编写的程序比较稳定,而且几种语言还要需要混合使用,比如迪蒙的网贷系统的语言,我觉得这个语言不能一个人去完成的,你要充分利用编程语言的优势,取长补短,这样开发出来的系统才是一个拿得出手的系统。