This commit is contained in:
joy.zhou
2019-07-31 14:34:56 +08:00
parent 913bff4ed5
commit 3ff0f170c6
7 changed files with 137 additions and 88 deletions
+6 -2
View File
@@ -14,6 +14,7 @@ import (
"github.com/fhmq/hmq/broker/lib/sessions"
"github.com/fhmq/hmq/broker/lib/topics"
pb "github.com/fhmq/hmq/grpc"
"github.com/fhmq/hmq/plugins"
"github.com/eclipse/paho.mqtt.golang/packets"
@@ -42,11 +43,11 @@ type Broker struct {
tlsConfig *tls.Config
wpool *pool.WorkerPool
clients sync.Map
remotes sync.Map
nodes map[string]interface{}
clusterPool chan *Message
topicsMgr *topics.Manager
sessionMgr *sessions.Manager
rpcClient map[string]pb.HMQServiceClient
pluginAuthHTTP bool
pluginKafka bool
}
@@ -130,7 +131,7 @@ func (b *Broker) Start() {
return
}
go initRPCService()
go b.initRPCService()
go InitHTTPMoniter(b)
@@ -369,6 +370,8 @@ func (b *Broker) handleConnection(typ int, conn net.Conn) {
if ok {
ol.Close()
}
} else {
b.QueryConnect(cid)
}
b.clients.Store(cid, c)
b.OnlineOfflineNotification(cid, true)
@@ -426,6 +429,7 @@ func (b *Broker) PublishMessage(packet *packets.PublishPacket) {
publish(sub, packet)
}
b.DeliverMessage(packet)
}
func (b *Broker) OnlineOfflineNotification(clientID string, online bool) {
+14 -33
View File
@@ -17,26 +17,20 @@ import (
)
type Config struct {
Worker int `json:"workerNum"`
Host string `json:"host"`
Port string `json:"port"`
Cluster RouteInfo `json:"cluster"`
Router string `json:"router"`
TlsHost string `json:"tlsHost"`
TlsPort string `json:"tlsPort"`
WsPath string `json:"wsPath"`
WsPort string `json:"wsPort"`
WsTLS bool `json:"wsTLS"`
TlsInfo TLSInfo `json:"tlsInfo"`
Acl bool `json:"acl"`
AclConf string `json:"aclConf"`
Debug bool `json:"debug"`
Plugins []string `json:"plugins"`
}
type RouteInfo struct {
Host string `json:"host"`
Port string `json:"port"`
Worker int `json:"workerNum"`
Host string `json:"host"`
Port string `json:"port"`
Router string `json:"router"`
TlsHost string `json:"tlsHost"`
TlsPort string `json:"tlsPort"`
WsPath string `json:"wsPath"`
WsPort string `json:"wsPort"`
WsTLS bool `json:"wsTLS"`
TlsInfo TLSInfo `json:"tlsInfo"`
Acl bool `json:"acl"`
AclConf string `json:"aclConf"`
Debug bool `json:"debug"`
Plugins []string `json:"plugins"`
}
type TLSInfo struct {
@@ -78,8 +72,6 @@ func ConfigureConfig(args []string) (*Config, error) {
fs.StringVar(&config.Port, "port", "1883", "Port to listen on.")
fs.StringVar(&config.Port, "p", "1883", "Port to listen on.")
fs.StringVar(&config.Host, "host", "0.0.0.0", "Network host to listen on")
fs.StringVar(&config.Cluster.Port, "cp", "", "Cluster port from which members can connect.")
fs.StringVar(&config.Cluster.Port, "clusterport", "", "Cluster port from which members can connect.")
fs.StringVar(&config.Router, "r", "", "Router who maintenance cluster info")
fs.StringVar(&config.Router, "router", "", "Router who maintenance cluster info")
fs.StringVar(&config.WsPort, "ws", "", "port for ws to listen on")
@@ -161,17 +153,6 @@ func (config *Config) check() error {
}
}
if config.Cluster.Port != "" {
if config.Cluster.Host == "" {
config.Cluster.Host = "0.0.0.0"
}
}
if config.Router != "" {
if config.Cluster.Port == "" {
return errors.New("cluster port is null")
}
}
if config.TlsPort != "" {
if config.TlsInfo.CertFile == "" || config.TlsInfo.KeyFile == "" {
log.Error("tls config error, no cert or key file.")
+4 -4
View File
@@ -15,7 +15,7 @@ func (c *client) SendInfo() {
if c.status == Disconnected {
return
}
url := c.info.localIP + ":" + c.broker.config.Cluster.Port
url := c.info.localIP + ":10011"
infoMsg := NewInfo(c.broker.id, url, false)
err := c.WriterPacket(infoMsg)
@@ -102,9 +102,9 @@ func (c *client) ProcessInfo(packet *packets.PublishPacket) {
url, ok := rurl.(string)
if ok {
exist := b.CheckRemoteExist(rid, url)
if !exist {
//todo new rpc client
//todo new rpc client
if _, exist := b.rpcClient[rid]; !exist {
b.initRPCClient(rid, url)
}
}
-16
View File
@@ -88,19 +88,3 @@ func (b *Broker) checkNodeExist(id, url string) bool {
}
return false
}
func (b *Broker) CheckRemoteExist(remoteID, url string) bool {
exist := false
b.remotes.Range(func(key, value interface{}) bool {
v, ok := value.(*client)
if ok {
if v.route.remoteUrl == url {
v.route.remoteID = remoteID
exist = true
return false
}
}
return true
})
return exist
}
+73 -12
View File
@@ -13,11 +13,7 @@ import (
"google.golang.org/grpc/reflection"
)
var (
rpcClient = make(map[string]pb.HMQServiceClient)
)
func initRPCService() {
func (b *Broker) initRPCService() {
lis, err := net.Listen("tcp", ":10011")
if err != nil {
log.Error("failed to listen: ", zap.Error(err))
@@ -27,17 +23,17 @@ func initRPCService() {
s := grpc.NewServer(grpc.KeepaliveParams(keepalive.ServerParameters{
Time: 30 * time.Minute,
}))
pb.RegisterHMQServiceServer(s, &HMQ{})
pb.RegisterHMQServiceServer(s, &HMQ{b: b})
reflection.Register(s)
if err := s.Serve(lis); err != nil {
log.Error("failed to serve: ", zap.Error(err))
}
}
func initRPCClient(url string) {
func (b *Broker) initRPCClient(id, url string) {
conn, err := grpc.Dial(url,
grpc.WithInsecure(),
grpc.WithKeepaliveParams(keepalive.ClientParameters{ // avoid 'code = Unavailable desc = transport is closing' error
grpc.WithKeepaliveParams(keepalive.ClientParameters{
Time: 30 * time.Minute,
}))
if err != nil {
@@ -45,24 +41,89 @@ func initRPCClient(url string) {
}
cli := pb.NewHMQServiceClient(conn)
rpcClient[url] = cli
b.rpcClient[id] = cli
}
type HMQ struct {
b *Broker
}
func (h *HMQ) QuerySubscribe(ctx context.Context, in *pb.QuerySubscribeRequest) (*pb.Response, error) {
return nil, nil
resp := &pb.Response{
RetCode: 0,
}
topic := in.Topic
qos := in.Qos
if qos > 1 {
resp.RetCode = 404
return resp, nil
}
b := h.b
var subs []interface{}
var qoss []byte
err := b.topicsMgr.Subscribers([]byte(topic), byte(qos), &subs, &qoss)
if err != nil {
log.Error("search sub client error, ", zap.Error(err))
resp.RetCode = 404
}
if len(subs) == 0 {
resp.RetCode = 404
}
return resp, nil
}
func (h *HMQ) QueryConnect(ctx context.Context, in *pb.QueryConnectRequest) (*pb.Response, error) {
return nil, nil
resp := &pb.Response{
RetCode: 0,
}
b := h.b
cli, exist := b.clients.Load(in.ClientID)
if exist {
client := cli.(*client)
client.Close()
}
return resp, nil
}
func (h *HMQ) DeliverMessage(ctx context.Context, in *pb.DeliverMessageRequest) (*pb.Response, error) {
return nil, nil
b := h.b
p := packets.NewControlPacket(packets.Publish).(*packets.PublishPacket)
p.TopicName = in.Topic
p.Payload = in.Payload
p.Retain = false
b.PublishMessage(p)
resp := &pb.Response{
RetCode: 0,
}
return resp, nil
}
func (b *Broker) DeliverMessage(packet *packets.PublishPacket) {
//TODO Query and Deliver Message
for _, client := range b.rpcClient {
resp, err := client.QuerySubscribe(context.Background(), &pb.QuerySubscribeRequest{Topic: packet.TopicName, Qos: int32(packet.Qos)})
if err != nil {
log.Error("rpc request error:", zap.Error(err))
continue
}
if resp.RetCode == 0 {
client.DeliverMessage(context.Background(), &pb.DeliverMessageRequest{Topic: packet.TopicName, Payload: packet.Payload})
}
}
}
func (b *Broker) QueryConnect(clientID string) {
//TODO Query and Deliver Message
for _, client := range b.rpcClient {
client.QueryConnect(context.Background(), &pb.QueryConnectRequest{ClientID: clientID})
}
}