pet-ai/server/websocket/enter.go

110 lines
2.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package websocket
import (
"encoding/json"
"time"
"github.com/flipped-aurora/gin-vue-admin/server/global"
"github.com/gin-gonic/gin"
"github.com/olahol/melody"
)
// HandleConnection 处理WebSocket连接
func HandleConnection(ctx *gin.Context) {
// 从中间件获取用户ID
userId, exists := ctx.Get("userId")
if !exists {
ctx.JSON(401, gin.H{"error": "用户认证失败"})
return
}
// 升级为WebSocket连接并存储用户信息
global.MELODY.HandleRequestWithKeys(ctx.Writer, ctx.Request, map[string]interface{}{
"userId": userId,
})
}
// SendMessage 发送消息到WebSocket连接
func SendMessage(s *melody.Session, message interface{}) error {
data, err := json.Marshal(message)
if err != nil {
return err
}
return s.Write(data)
}
// SendErrorMessage 发送错误消息
func SendErrorMessage(s *melody.Session, errorMsg string) {
SendMessage(s, NewErrorEvent(errorMsg))
}
// BroadcastToUser 向指定用户广播消息
func BroadcastToUser(userID uint, message interface{}) error {
messageBytes, err := json.Marshal(message)
if err != nil {
return err
}
// 遍历所有连接,找到对应用户的连接
return global.MELODY.BroadcastFilter(messageBytes, func(s *melody.Session) bool {
if userIdInterface, exists := s.Get("userId"); exists {
if userId, ok := userIdInterface.(uint); ok {
return userId == userID
}
}
return false
})
}
// BroadcastMessageToUser 向指定用户广播流式消息
func BroadcastMessageToUser(userID uint, delta string) error {
return BroadcastToUser(userID, NewMessageEvent(delta))
}
// BroadcastErrorToUser 向指定用户广播错误消息
func BroadcastErrorToUser(userID uint, errorMsg string) error {
return BroadcastToUser(userID, NewErrorEvent(errorMsg))
}
// BroadcastDoneToUser 向指定用户广播完成消息
func BroadcastDoneToUser(userID uint, message, sessionId string) error {
return BroadcastToUser(userID, NewDoneEvent(message, sessionId))
}
// GetConnectedUserCount 获取当前连接的用户数量
func GetConnectedUserCount() int {
count := 0
global.MELODY.BroadcastFilter([]byte{}, func(s *melody.Session) bool {
if _, exists := s.Get("userId"); exists {
count++
}
return false // 不实际发送消息,只统计
})
return count
}
// SendPingToUser 向指定用户发送心跳消息
func SendPingToUser(userID uint) error {
pingMsg := Message{
Type: "ping",
Data: map[string]interface{}{
"timestamp": time.Now().Unix(),
},
}
return BroadcastToUser(userID, pingMsg)
}
// IsUserConnected 检查用户是否在线
func IsUserConnected(userID uint) bool {
connected := false
global.MELODY.BroadcastFilter([]byte{}, func(s *melody.Session) bool {
if userIdInterface, exists := s.Get("userId"); exists {
if userId, ok := userIdInterface.(uint); ok && userId == userID {
connected = true
}
}
return false // 不实际发送消息,只检查
})
return connected
}