github.com/turingchain2020/turingchain@v1.1.21/system/p2p/dht/protocol/peer/pubsub.go (about) 1 package peer 2 3 import ( 4 "fmt" 5 6 "github.com/turingchain2020/turingchain/queue" 7 "github.com/turingchain2020/turingchain/system/p2p/dht/extension" 8 "github.com/turingchain2020/turingchain/types" 9 "github.com/libp2p/go-libp2p-core/peer" 10 ) 11 12 //处理订阅topic的请求 13 func (p *Protocol) handleEventSubTopic(msg *queue.Message) { 14 //先检查是否已经订阅相关topic 15 //接收turingchain其他模块发来的请求消息 16 subtopic := msg.GetData().(*types.SubTopic) 17 topic := subtopic.GetTopic() 18 //check topic 19 moduleName := subtopic.GetModule() 20 //模块名,用来收到订阅的消息后转发给对应的模块名 21 if !p.Pubsub.HasTopic(topic) { 22 err := p.Pubsub.JoinAndSubTopic(topic, p.subCallBack) //订阅topic 23 if err != nil { 24 log.Error("peerPubSub", "err", err) 25 msg.Reply(p.QueueClient.NewMessage("", types.EventSubTopic, &types.Reply{IsOk: false, Msg: []byte(err.Error())})) 26 return 27 } 28 } 29 30 var reply types.SubTopicReply 31 reply.Status = true 32 reply.Msg = fmt.Sprintf("subtopic %v success", topic) 33 msg.Reply(p.QueueClient.NewMessage("", types.EventSubTopic, &types.Reply{IsOk: true, Msg: types.Encode(&reply)})) 34 35 p.topicMutex.Lock() 36 defer p.topicMutex.Unlock() 37 38 var modules map[string]bool 39 v, ok := p.topicModule.Load(topic) 40 if ok { 41 modules = v.(map[string]bool) 42 } else { 43 modules = make(map[string]bool) 44 } 45 modules[moduleName] = true 46 p.topicModule.Store(topic, modules) 47 //接收订阅的消息 48 } 49 50 //处理收到的数据 51 func (p *Protocol) subCallBack(topic string, msg extension.SubMsg) { 52 p.topicMutex.RLock() 53 defer p.topicMutex.RUnlock() 54 55 modules, ok := p.topicModule.Load(topic) 56 if !ok { 57 return 58 } 59 60 for moduleName := range modules.(map[string]bool) { 61 newMsg := p.QueueClient.NewMessage(moduleName, types.EventReceiveSubData, &types.TopicData{Topic: topic, From: peer.ID(msg.From).String(), Data: msg.Data}) //加入到输出通道) 62 _ = p.QueueClient.Send(newMsg, false) 63 } 64 } 65 66 //获取所有已经订阅的topic 67 func (p *Protocol) handleEventGetTopics(msg *queue.Message) { 68 _, ok := msg.GetData().(*types.FetchTopicList) 69 if !ok { 70 msg.Reply(p.QueueClient.NewMessage("", types.EventFetchTopics, &types.Reply{IsOk: false, Msg: []byte("need *types.FetchTopicList")})) 71 return 72 } 73 //获取topic列表 74 topics := p.Pubsub.GetTopics() 75 var reply types.TopicList 76 reply.Topics = topics 77 msg.Reply(p.QueueClient.NewMessage("", types.EventFetchTopics, &types.Reply{IsOk: true, Msg: types.Encode(&reply)})) 78 } 79 80 //删除已经订阅的某一个topic 81 func (p *Protocol) handleEventRemoveTopic(msg *queue.Message) { 82 p.topicMutex.Lock() 83 defer p.topicMutex.Unlock() 84 85 v, ok := msg.GetData().(*types.RemoveTopic) 86 if !ok { 87 msg.Reply(p.QueueClient.NewMessage("", types.EventRemoveTopic, &types.Reply{IsOk: false, Msg: []byte("need *types.RemoveTopic")})) 88 return 89 } 90 91 vmodules, ok := p.topicModule.Load(v.GetTopic()) 92 if !ok || len(vmodules.(map[string]bool)) == 0 { 93 msg.Reply(p.QueueClient.NewMessage("", types.EventRemoveTopic, &types.Reply{IsOk: false, Msg: []byte("this module no sub this topic")})) 94 return 95 } 96 modules := vmodules.(map[string]bool) 97 delete(modules, v.GetModule()) //删除消息推送的module 98 var reply types.RemoveTopicReply 99 reply.Topic = v.GetTopic() 100 reply.Status = true 101 102 if len(modules) != 0 { 103 msg.Reply(p.QueueClient.NewMessage("", types.EventRemoveTopic, &types.Reply{IsOk: true, Msg: types.Encode(&reply)})) 104 return 105 } 106 107 p.Pubsub.RemoveTopic(v.GetTopic()) 108 msg.Reply(p.QueueClient.NewMessage("", types.EventRemoveTopic, &types.Reply{IsOk: true, Msg: types.Encode(&reply)})) 109 } 110 111 //发布Topic消息 112 func (p *Protocol) handleEventPubMsg(msg *queue.Message) { 113 v, ok := msg.GetData().(*types.PublishTopicMsg) 114 if !ok { 115 msg.Reply(p.QueueClient.NewMessage("", types.EventPubTopicMsg, &types.Reply{IsOk: false, Msg: []byte("need *types.PublishTopicMsg")})) 116 return 117 } 118 var isOK = true 119 replyInfo := "push success" 120 err := p.Pubsub.Publish(v.GetTopic(), v.GetMsg()) 121 if err != nil { 122 //publish msg failed 123 isOK = false 124 replyInfo = err.Error() 125 } 126 msg.Reply(p.QueueClient.NewMessage("", types.EventPubTopicMsg, &types.Reply{IsOk: isOK, Msg: []byte(replyInfo)})) 127 }