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  }