phase 10
This commit is contained in:
@@ -13,6 +13,7 @@ import (
|
||||
|
||||
"github.com/uopi/uopi/internal/broker"
|
||||
"github.com/uopi/uopi/internal/datasource"
|
||||
"github.com/uopi/uopi/internal/metrics"
|
||||
)
|
||||
|
||||
// ── Incoming message types ────────────────────────────────────────────────────
|
||||
@@ -95,6 +96,8 @@ func (h *wsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
h.log.Error("ws accept failed", "err", err)
|
||||
return
|
||||
}
|
||||
metrics.IncWsConns()
|
||||
defer metrics.DecWsConns()
|
||||
|
||||
ctx, cancel := context.WithCancel(r.Context())
|
||||
defer cancel()
|
||||
@@ -191,6 +194,7 @@ func (c *wsClient) writeLoop(ctx context.Context) {
|
||||
if err := c.conn.Write(ctx, websocket.MessageText, msg); err != nil {
|
||||
return
|
||||
}
|
||||
metrics.IncMsgOut()
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
@@ -199,6 +203,7 @@ func (c *wsClient) writeLoop(ctx context.Context) {
|
||||
|
||||
// handleMessage parses and routes a single incoming client message.
|
||||
func (c *wsClient) handleMessage(ctx context.Context, data []byte) {
|
||||
metrics.IncMsgIn()
|
||||
var msg inMsg
|
||||
if err := json.Unmarshal(data, &msg); err != nil {
|
||||
c.sendError(ctx, "PARSE_ERROR", "invalid JSON: "+err.Error())
|
||||
@@ -264,6 +269,17 @@ func (c *wsClient) handleWrite(ctx context.Context, msg inMsg) {
|
||||
return
|
||||
}
|
||||
|
||||
// Enforce write permission before touching the value payload.
|
||||
meta, err := ds.GetMetadata(ctx, msg.Name)
|
||||
if err != nil {
|
||||
c.sendError(ctx, "NOT_FOUND", "unknown signal: "+msg.Name)
|
||||
return
|
||||
}
|
||||
if !meta.Writable {
|
||||
c.sendError(ctx, "NOT_WRITABLE", "signal is read-only: "+msg.Name)
|
||||
return
|
||||
}
|
||||
|
||||
// Decode the JSON value as the appropriate Go type.
|
||||
var value any
|
||||
if err := json.Unmarshal(msg.Value, &value); err != nil {
|
||||
@@ -271,12 +287,14 @@ func (c *wsClient) handleWrite(ctx context.Context, msg inMsg) {
|
||||
return
|
||||
}
|
||||
|
||||
metrics.IncWrites()
|
||||
if err := ds.Write(ctx, msg.Name, value); err != nil {
|
||||
c.sendError(ctx, "WRITE_ERROR", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func (c *wsClient) handleHistory(ctx context.Context, msg inMsg) {
|
||||
metrics.IncHistoryReqs()
|
||||
ds, ok := c.broker.Source(msg.DS)
|
||||
if !ok {
|
||||
c.sendError(ctx, "NOT_FOUND", "unknown data source: "+msg.DS)
|
||||
|
||||
Reference in New Issue
Block a user