feat(api): 实现 WebSocket 服务器的订阅功能
- 将 clients map 的值从 bool 改为 string,用于存储订阅的主题 - 在 handleWebSocket 函数中实现客户端注册逻辑 - 在 handleClient 函数中处理订阅请求,并保存订阅的主题 - 修改 handleDataChange 函数,仅向订阅了相应主题的客户端广播事件 - 在 DataPointID 结构中添加 MetricHash 方法,用于生成主题哈希值
This commit is contained in:
parent
a7d5c66fb0
commit
f97b0b2ea7
|
@ -20,7 +20,7 @@ type WebSocketServer struct {
|
||||||
dataManager *manager.DataManager
|
dataManager *manager.DataManager
|
||||||
router *gin.Engine
|
router *gin.Engine
|
||||||
server *http.Server
|
server *http.Server
|
||||||
clients map[*websocket.Conn]bool
|
clients map[*websocket.Conn]string
|
||||||
clientsLock sync.RWMutex
|
clientsLock sync.RWMutex
|
||||||
upgrader websocket.Upgrader
|
upgrader websocket.Upgrader
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ func NewWebSocketServer(dataManager *manager.DataManager) *WebSocketServer {
|
||||||
server := &WebSocketServer{
|
server := &WebSocketServer{
|
||||||
dataManager: dataManager,
|
dataManager: dataManager,
|
||||||
router: router,
|
router: router,
|
||||||
clients: make(map[*websocket.Conn]bool),
|
clients: make(map[*websocket.Conn]string),
|
||||||
upgrader: websocket.Upgrader{
|
upgrader: websocket.Upgrader{
|
||||||
CheckOrigin: func(r *http.Request) bool {
|
CheckOrigin: func(r *http.Request) bool {
|
||||||
return true // 允许所有来源的WebSocket连接
|
return true // 允许所有来源的WebSocket连接
|
||||||
|
@ -81,7 +81,7 @@ func (s *WebSocketServer) handleWebSocket(c *gin.Context) {
|
||||||
|
|
||||||
// 注册客户端
|
// 注册客户端
|
||||||
s.clientsLock.Lock()
|
s.clientsLock.Lock()
|
||||||
s.clients[conn] = true
|
s.clients[conn] = ""
|
||||||
s.clientsLock.Unlock()
|
s.clientsLock.Unlock()
|
||||||
|
|
||||||
// 处理客户端消息
|
// 处理客户端消息
|
||||||
|
@ -116,9 +116,12 @@ func (s *WebSocketServer) handleClient(conn *websocket.Conn) {
|
||||||
log.Printf("Failed to parse subscription request: %v", err)
|
log.Printf("Failed to parse subscription request: %v", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
id := model.DataPointID{
|
||||||
|
DeviceID: req.DeviceID,
|
||||||
|
MetricCode: req.MetricCode,
|
||||||
|
}
|
||||||
|
s.clients[conn] = id.MetricHash()
|
||||||
|
|
||||||
// 处理订阅请求
|
|
||||||
// TODO: 实现订阅逻辑
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,6 +136,7 @@ func (s *WebSocketServer) handleDataChange(id model.DataPointID, value model.Dat
|
||||||
Value: value.Value,
|
Value: value.Value,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
metricHash := id.MetricHash()
|
||||||
// 序列化事件
|
// 序列化事件
|
||||||
data, err := json.Marshal(event)
|
data, err := json.Marshal(event)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -142,7 +146,10 @@ func (s *WebSocketServer) handleDataChange(id model.DataPointID, value model.Dat
|
||||||
|
|
||||||
// 广播事件
|
// 广播事件
|
||||||
s.clientsLock.RLock()
|
s.clientsLock.RLock()
|
||||||
for client := range s.clients {
|
for client, subject := range s.clients {
|
||||||
|
if subject != metricHash {
|
||||||
|
continue // 忽略非匹配的订阅
|
||||||
|
}
|
||||||
if err := client.WriteMessage(websocket.TextMessage, data); err != nil {
|
if err := client.WriteMessage(websocket.TextMessage, data); err != nil {
|
||||||
log.Printf("Failed to send data change event: %v", err)
|
log.Printf("Failed to send data change event: %v", err)
|
||||||
client.Close()
|
client.Close()
|
||||||
|
|
|
@ -19,6 +19,10 @@ func (id DataPointID) String() string {
|
||||||
return id.Hash()
|
return id.Hash()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (id DataPointID) MetricHash() string {
|
||||||
|
return fmt.Sprintf("%s:%s", id.DeviceID, id.MetricCode)
|
||||||
|
}
|
||||||
|
|
||||||
// Equal 判断两个数据点标识是否相等
|
// Equal 判断两个数据点标识是否相等
|
||||||
func (id DataPointID) Equal(other DataPointID) bool {
|
func (id DataPointID) Equal(other DataPointID) bool {
|
||||||
if id.DeviceID != other.DeviceID || id.MetricCode != other.MetricCode {
|
if id.DeviceID != other.DeviceID || id.MetricCode != other.MetricCode {
|
||||||
|
|
Loading…
Reference in New Issue