Files
bj_power/bj_power_mes/internal/sse/sse.go
T
SunYF 92f0439d89 feat: 新增产线看板功能并优化多端系统体验
1. 新增SSE看板广播机制,业务操作后主动推送刷新事件
2. 新增产线工序横道图与工位状态展示面板
3. 移除dashboard无用的three.js依赖
4. 重构WMS客户端布局与WMS前端资源哈希
5. 新增工位终端时钟图标与大屏自适应布局
6. 新增系统截图脚本与说明书生成工具
7. 修复多处代码细节与空值处理逻辑
2026-09-04 17:31:18 +08:00

82 lines
1.5 KiB
Go

package sse
import (
"fmt"
"net/http"
"sync"
)
// SseMsg SSE 事件消息
type SseMsg struct {
Type string // 事件名,如表单名 dashboard.*
Data string // JSON 字符串
}
// Hub SSE 推送中心(支持看板局部刷新)
type Hub struct {
mu sync.Mutex
clients map[chan SseMsg]struct{}
closed map[chan SseMsg]bool
}
func NewHub() *Hub {
return &Hub{clients: make(map[chan SseMsg]struct{})}
}
// Add 新增客户端
func (h *Hub) Add() chan SseMsg {
ch := make(chan SseMsg, 16)
h.mu.Lock()
h.clients[ch] = struct{}{}
h.mu.Unlock()
return ch
}
func (h *Hub) Remove(ch chan SseMsg) {
h.mu.Lock()
if _, ok := h.clients[ch]; ok {
delete(h.clients, ch)
close(ch)
}
h.mu.Unlock()
}
// Publish 广播事件
func (h *Hub) Publish(typ string, data string) {
h.mu.Lock()
defer h.mu.Unlock()
for ch := range h.clients {
select {
case ch <- SseMsg{Type: typ, Data: data}:
default:
}
}
}
// Handler SSE 长连接端点
func (h *Hub) Handler(w http.ResponseWriter, r *http.Request) {
fl, ok := w.(http.Flusher)
if !ok {
http.Error(w, "streaming unsupported", http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "text/event-stream")
w.Header().Set("Cache-Control", "no-cache")
w.Header().Set("Connection", "keep-alive")
ch := h.Add()
defer h.Remove(ch)
h.Publish("dashboard.hello", "{}")
for {
select {
case m := <-ch:
if _, err := fmt.Fprintf(w, "event: %s\ndata: %s\n\n", m.Type, m.Data); err != nil {
return
}
fl.Flush()
case <-r.Context().Done():
return
}
}
}