|
@@ -1,9 +1,12 @@
|
|
|
package server
|
|
|
|
|
|
import (
|
|
|
+ "context"
|
|
|
+ "encoding/json"
|
|
|
+ "fmt"
|
|
|
"sync"
|
|
|
|
|
|
- "sikey.com/websocket/stackexchange/redis"
|
|
|
+ "github.com/redis/go-redis/v9"
|
|
|
"sikey.com/websocket/utils/zlog"
|
|
|
)
|
|
|
|
|
@@ -11,40 +14,42 @@ type HubConfig struct {
|
|
|
ConnectSize int
|
|
|
DisconnectSize int
|
|
|
MessageSize int
|
|
|
-
|
|
|
- // StackExchange *stackexchange.RedisStackExchange
|
|
|
+ ServerId string // serverId 服务器ID
|
|
|
}
|
|
|
|
|
|
type Hub struct {
|
|
|
- remotelyClients map[string]*Client
|
|
|
- remotelyMutex sync.RWMutex
|
|
|
- clients map[string]*Client
|
|
|
- mutex sync.RWMutex
|
|
|
+ serverId string // serverId 服务器ID
|
|
|
+ rdb redis.UniversalClient
|
|
|
|
|
|
+ clients map[string]*Client
|
|
|
+ mutex sync.RWMutex
|
|
|
Connect chan *Client
|
|
|
Disconnect chan *Client
|
|
|
-
|
|
|
- Message chan *Message
|
|
|
-
|
|
|
- StackExchange *redis.StackExchange
|
|
|
+ Message chan *Message
|
|
|
}
|
|
|
|
|
|
func NewHub(cfg HubConfig) *Hub {
|
|
|
hub := &Hub{
|
|
|
- remotelyClients: make(map[string]*Client),
|
|
|
- remotelyMutex: sync.RWMutex{},
|
|
|
- clients: make(map[string]*Client),
|
|
|
- mutex: sync.RWMutex{},
|
|
|
+ serverId: cfg.ServerId,
|
|
|
+ rdb: redis.NewUniversalClient(&redis.UniversalOptions{
|
|
|
+ Addrs: []string{"106.75.230.4:6379"},
|
|
|
+ Password: "sikey!Q@W#E456",
|
|
|
+ DB: 0,
|
|
|
+ }),
|
|
|
+
|
|
|
+ clients: make(map[string]*Client),
|
|
|
+ mutex: sync.RWMutex{},
|
|
|
|
|
|
Connect: make(chan *Client, cfg.ConnectSize),
|
|
|
Disconnect: make(chan *Client, cfg.DisconnectSize),
|
|
|
Message: make(chan *Message, cfg.MessageSize),
|
|
|
}
|
|
|
|
|
|
- hub.StackExchange = redis.NewStackExchange()
|
|
|
-
|
|
|
go hub.run()
|
|
|
- go hub.remotely() // 远程消息
|
|
|
+
|
|
|
+ go hub.remotelyEvent() // 远程事件
|
|
|
+ //go hub.remotelyMessageReader()
|
|
|
+ //go hub.remotelyMessageWriter()
|
|
|
return hub
|
|
|
}
|
|
|
|
|
@@ -52,56 +57,61 @@ func (h *Hub) run() {
|
|
|
for {
|
|
|
select {
|
|
|
case client := <-h.Connect:
|
|
|
- if client.isRemotely {
|
|
|
- h.remotelyClients[client.UserId] = client
|
|
|
- } else {
|
|
|
- h.clients[client.UserId] = client
|
|
|
- }
|
|
|
+ h.clients[client.UserId] = client
|
|
|
case client := <-h.Disconnect:
|
|
|
close(client.Send)
|
|
|
- if client.isRemotely {
|
|
|
- delete(h.remotelyClients, client.UserId)
|
|
|
- } else {
|
|
|
- delete(h.clients, client.UserId)
|
|
|
- }
|
|
|
+ delete(h.clients, client.UserId)
|
|
|
case message := <-h.Message:
|
|
|
if client, ok := h.clients[message.receiver]; ok {
|
|
|
- client.Send <- message
|
|
|
- } else {
|
|
|
- // 不在同一台服务器, 这里将消息发送至拓展应用
|
|
|
- if client != nil {
|
|
|
- client.RemotelyMessage <- message
|
|
|
+ if client.isRemotely {
|
|
|
+ ctx := context.Background()
|
|
|
+ err := h.rdb.Publish(ctx, messageChannelEvent, message).Err()
|
|
|
+ if err != nil {
|
|
|
+ zlog.Error(err)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ client.Send <- message
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-func (h *Hub) remotely() {
|
|
|
- for {
|
|
|
+var (
|
|
|
+ connectChannelEvent = "client.event.connect"
|
|
|
+ disconnectChannelEvent = "client.event.disconnect"
|
|
|
+ messageChannelEvent = "client.event.message"
|
|
|
+)
|
|
|
|
|
|
- zlog.Info("Remotely client actions monitoring.")
|
|
|
- // km, err := h.exchange.ReadMessage()
|
|
|
- // if err != nil {
|
|
|
- // zlog.Error(err)
|
|
|
- // }
|
|
|
+func (h *Hub) remotelyEvent() {
|
|
|
+ ctx := context.TODO()
|
|
|
+ pubsub := h.rdb.PSubscribe(ctx, "client.event.*")
|
|
|
+ defer pubsub.Close()
|
|
|
+
|
|
|
+ for {
|
|
|
+ rMsg, err := pubsub.ReceiveMessage(ctx)
|
|
|
+ if err != nil {
|
|
|
+ zlog.Error(err)
|
|
|
+ }
|
|
|
|
|
|
- // // Create new a remote client
|
|
|
- // remotelyClient := &Client{
|
|
|
- // isRemotely: true, // mark remotely client
|
|
|
- // UserId: string(km.Value),
|
|
|
- // Send: make(chan *Message, 256),
|
|
|
- // hub: h,
|
|
|
- // }
|
|
|
- // switch {
|
|
|
- // case bytes.Equal(km.Key, stackexchange.StackExchangeOnline):
|
|
|
- // h.Connect <- remotelyClient
|
|
|
- // zlog.Info("Remotely client online: ", remotelyClient.UserId)
|
|
|
- // case bytes.Equal(km.Key, stackexchange.StackExchangeOffline):
|
|
|
- // h.Disconnect <- remotelyClient
|
|
|
- // zlog.Info("Remotely client offline: ", remotelyClient.UserId)
|
|
|
- // case bytes.Equal(km.Key, stackexchange.StackExchangeMessaging):
|
|
|
- // h.Message <- deserializeMessage(km.Value)
|
|
|
- // }
|
|
|
+ switch rMsg.Channel {
|
|
|
+ case connectChannelEvent:
|
|
|
+ h.Connect <- &Client{
|
|
|
+ hub: h,
|
|
|
+ UserId: rMsg.Payload,
|
|
|
+ isRemotely: true,
|
|
|
+ Send: make(chan *Message),
|
|
|
+ }
|
|
|
+ case disconnectChannelEvent:
|
|
|
+ h.Disconnect <- h.clients[rMsg.Payload]
|
|
|
+ case messageChannelEvent:
|
|
|
+ var message Message
|
|
|
+ if err = json.Unmarshal([]byte(rMsg.Payload), &message); err != nil {
|
|
|
+ zlog.Error(err)
|
|
|
+ break
|
|
|
+ }
|
|
|
+ h.Message <- &message
|
|
|
+ }
|
|
|
+ fmt.Println(rMsg)
|
|
|
}
|
|
|
}
|