github.com/jingruilea/kubeedge@v1.2.0-beta.0.0.20200410162146-4bb8902b3879/edge/pkg/eventbus/mqtt/client.go (about) 1 package mqtt 2 3 import ( 4 "encoding/base64" 5 "fmt" 6 "strconv" 7 "strings" 8 "time" 9 10 MQTT "github.com/eclipse/paho.mqtt.golang" 11 "k8s.io/klog" 12 13 beehiveContext "github.com/kubeedge/beehive/pkg/core/context" 14 "github.com/kubeedge/beehive/pkg/core/model" 15 "github.com/kubeedge/kubeedge/edge/pkg/common/modules" 16 "github.com/kubeedge/kubeedge/edge/pkg/eventbus/common/util" 17 ) 18 19 var ( 20 // MQTTHub client 21 MQTTHub *Client 22 // GroupID stands for group id 23 GroupID string 24 // ConnectedTopic to send connect event 25 ConnectedTopic = "$hw/events/connected/%s" 26 // DisconnectedTopic to send disconnect event 27 DisconnectedTopic = "$hw/events/disconnected/%s" 28 // MemberGet to get membership device 29 MemberGet = "$hw/events/edgeGroup/%s/membership/get" 30 // MemberGetRes to get membership device 31 MemberGetRes = "$hw/events/edgeGroup/%s/membership/get/result" 32 // MemberDetail which edge-client should be pub when service start 33 MemberDetail = "$hw/events/edgeGroup/%s/membership/detail" 34 // MemberDetailRes MemberDetail topic resp 35 MemberDetailRes = "$hw/events/edgeGroup/%s/membership/detail/result" 36 // MemberUpdate updating of the twin 37 MemberUpdate = "$hw/events/edgeGroup/%s/membership/updated" 38 // GroupUpdate updates a edgegroup 39 GroupUpdate = "$hw/events/edgeGroup/%s/updated" 40 // GroupAuthGet get temperary aksk from cloudhub 41 GroupAuthGet = "$hw/events/edgeGroup/%s/authInfo/get" 42 // GroupAuthGetRes temperary aksk from cloudhub 43 GroupAuthGetRes = "$hw/events/edgeGroup/%s/authInfo/get/result" 44 // SubTopics which edge-client should be sub 45 SubTopics = []string{ 46 "$hw/events/upload/#", 47 "$hw/events/device/+/state/update", 48 "$hw/events/device/+/twin/+", 49 "$hw/events/node/+/membership/get", 50 "SYS/dis/upload_records", 51 } 52 ) 53 54 // Client struct 55 type Client struct { 56 MQTTUrl string 57 PubCli MQTT.Client 58 SubCli MQTT.Client 59 } 60 61 // AccessInfo that deliever between edge-hub and cloud-hub 62 type AccessInfo struct { 63 Name string `json:"name"` 64 Type string `json:"type"` 65 Topic string `json:"topic"` 66 Content []byte `json:"content"` 67 } 68 69 func onPubConnectionLost(client MQTT.Client, err error) { 70 klog.Errorf("onPubConnectionLost with error: %v", err) 71 go MQTTHub.InitPubClient() 72 } 73 74 func onSubConnectionLost(client MQTT.Client, err error) { 75 klog.Errorf("onSubConnectionLost with error: %v", err) 76 go MQTTHub.InitSubClient() 77 } 78 79 func onSubConnect(client MQTT.Client) { 80 for _, t := range SubTopics { 81 token := client.Subscribe(t, 1, OnSubMessageReceived) 82 if rs, err := util.CheckClientToken(token); !rs { 83 klog.Errorf("edge-hub-cli subscribe topic: %s, %v", t, err) 84 return 85 } 86 klog.Infof("edge-hub-cli subscribe topic to %s", t) 87 } 88 } 89 90 // OnSubMessageReceived msg received callback 91 func OnSubMessageReceived(client MQTT.Client, message MQTT.Message) { 92 klog.Infof("OnSubMessageReceived receive msg from topic: %s", message.Topic()) 93 // for "$hw/events/device/+/twin/+", "$hw/events/node/+/membership/get", send to twin 94 // for other, send to hub 95 // for "SYS/dis/upload_records", no need to base64 topic 96 var target string 97 resource := base64.URLEncoding.EncodeToString([]byte(message.Topic())) 98 if strings.HasPrefix(message.Topic(), "$hw/events/device") || strings.HasPrefix(message.Topic(), "$hw/events/node") { 99 target = modules.TwinGroup 100 } else { 101 target = modules.HubGroup 102 if message.Topic() == "SYS/dis/upload_records" { 103 resource = "SYS/dis/upload_records" 104 } 105 } 106 // routing key will be $hw.<project_id>.events.user.bus.response.cluster.<cluster_id>.node.<node_id>.<base64_topic> 107 msg := model.NewMessage("").BuildRouter(modules.BusGroup, "user", 108 resource, "response").FillBody(string(message.Payload())) 109 klog.Info(fmt.Sprintf("received msg from mqttserver, deliver to %s with resource %s", target, resource)) 110 beehiveContext.SendToGroup(target, *msg) 111 } 112 113 // InitSubClient init sub client 114 func (mq *Client) InitSubClient() { 115 timeStr := strconv.FormatInt(time.Now().UnixNano()/1e6, 10) 116 right := len(timeStr) 117 if right > 10 { 118 right = 10 119 } 120 subID := fmt.Sprintf("hub-client-sub-%s", timeStr[0:right]) 121 subOpts := util.HubClientInit(mq.MQTTUrl, subID, "", "") 122 subOpts.OnConnect = onSubConnect 123 subOpts.AutoReconnect = false 124 subOpts.OnConnectionLost = onSubConnectionLost 125 mq.SubCli = MQTT.NewClient(subOpts) 126 util.LoopConnect(subID, mq.SubCli) 127 klog.Info("finish hub-client sub") 128 } 129 130 // InitPubClient init pub client 131 func (mq *Client) InitPubClient() { 132 timeStr := strconv.FormatInt(time.Now().UnixNano()/1e6, 10) 133 right := len(timeStr) 134 if right > 10 { 135 right = 10 136 } 137 pubID := fmt.Sprintf("hub-client-pub-%s", timeStr[0:right]) 138 pubOpts := util.HubClientInit(mq.MQTTUrl, pubID, "", "") 139 pubOpts.OnConnectionLost = onPubConnectionLost 140 pubOpts.AutoReconnect = false 141 mq.PubCli = MQTT.NewClient(pubOpts) 142 util.LoopConnect(pubID, mq.PubCli) 143 klog.Info("finish hub-client pub") 144 }