init
This commit is contained in:
119
Backend/internal/controller/websocket/ChatRoom.go
Normal file
119
Backend/internal/controller/websocket/ChatRoom.go
Normal file
@@ -0,0 +1,119 @@
|
||||
package websocket
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
"sync"
|
||||
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"github.com/gorilla/websocket"
|
||||
)
|
||||
|
||||
type ChatMessage struct {
|
||||
RoomId string `json:"roomId"`
|
||||
UserId string `json:"userId"`
|
||||
Message string `json:"message"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
var upgrader = websocket.Upgrader{CheckOrigin: func(r *http.Request) bool { return true }}
|
||||
var clients = make(map[*websocket.Conn]bool)
|
||||
var roomClients = make(map[string]map[*websocket.Conn]bool)
|
||||
var broadcast = make(chan ChatMessage, 256)
|
||||
var mutex = sync.RWMutex{}
|
||||
var once sync.Once
|
||||
|
||||
func HandleChatConnections(r *ghttp.Request) {
|
||||
once.Do(func() {
|
||||
go handleBroadcast()
|
||||
})
|
||||
|
||||
ws, err := upgrader.Upgrade(r.Response.Writer, r.Request, nil)
|
||||
if err != nil {
|
||||
log.Printf("upgrade error: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
mutex.Lock()
|
||||
clients[ws] = true
|
||||
mutex.Unlock()
|
||||
|
||||
defer func() {
|
||||
mutex.Lock()
|
||||
delete(clients, ws)
|
||||
for roomId, members := range roomClients {
|
||||
if _, ok := members[ws]; ok {
|
||||
delete(members, ws)
|
||||
if len(members) == 0 {
|
||||
delete(roomClients, roomId)
|
||||
}
|
||||
}
|
||||
}
|
||||
mutex.Unlock()
|
||||
ws.Close()
|
||||
}()
|
||||
|
||||
for {
|
||||
var msg ChatMessage
|
||||
err := ws.ReadJSON(&msg)
|
||||
if err != nil {
|
||||
log.Printf("read error: %v", err)
|
||||
break
|
||||
}
|
||||
|
||||
switch msg.Type {
|
||||
case "join":
|
||||
mutex.Lock()
|
||||
members, ok := roomClients[msg.RoomId]
|
||||
if !ok {
|
||||
members = make(map[*websocket.Conn]bool)
|
||||
roomClients[msg.RoomId] = members
|
||||
}
|
||||
members[ws] = true
|
||||
mutex.Unlock()
|
||||
case "leave":
|
||||
mutex.Lock()
|
||||
if members, ok := roomClients[msg.RoomId]; ok {
|
||||
delete(members, ws)
|
||||
if len(members) == 0 {
|
||||
delete(roomClients, msg.RoomId)
|
||||
}
|
||||
}
|
||||
mutex.Unlock()
|
||||
}
|
||||
|
||||
select {
|
||||
case broadcast <- msg:
|
||||
default:
|
||||
log.Printf("broadcast channel full, dropping message")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func handleBroadcast() {
|
||||
for {
|
||||
msg := <-broadcast
|
||||
mutex.RLock()
|
||||
members, ok := roomClients[msg.RoomId]
|
||||
if !ok {
|
||||
mutex.RUnlock()
|
||||
continue
|
||||
}
|
||||
for client := range members {
|
||||
err := client.WriteJSON(msg)
|
||||
if err != nil {
|
||||
log.Printf("write error: %v", err)
|
||||
client.Close()
|
||||
mutex.RUnlock()
|
||||
mutex.Lock()
|
||||
delete(members, client)
|
||||
if len(members) == 0 {
|
||||
delete(roomClients, msg.RoomId)
|
||||
}
|
||||
mutex.Unlock()
|
||||
mutex.RLock()
|
||||
}
|
||||
}
|
||||
mutex.RUnlock()
|
||||
}
|
||||
}
|
||||
65
Backend/internal/controller/websocket/websocket.go
Normal file
65
Backend/internal/controller/websocket/websocket.go
Normal file
@@ -0,0 +1,65 @@
|
||||
package websocket
|
||||
|
||||
//
|
||||
//import (
|
||||
// "net/http"
|
||||
//
|
||||
// "github.com/gogf/gf/v2/frame/g"
|
||||
// "github.com/gogf/gf/v2/net/ghttp"
|
||||
// "github.com/gorilla/websocket"
|
||||
//)
|
||||
//
|
||||
//// WebSocketController WebSocket 控制器
|
||||
//type WebSocketController struct{}
|
||||
//
|
||||
//// New 创建 WebSocket 控制器实例
|
||||
//func New() *WebSocketController {
|
||||
// return &WebSocketController{}
|
||||
//}
|
||||
//
|
||||
//// wsUpgrader WebSocket 升级器配置
|
||||
//var wsUpgrader = websocket.Upgrader{
|
||||
// // CheckOrigin 允许任何来源(开发环境)
|
||||
// // 生产环境中应该实现适当的来源检查以确保安全
|
||||
// CheckOrigin: func(r *http.Request) bool {
|
||||
// return true
|
||||
// },
|
||||
// // Error 处理升级失败的错误
|
||||
// Error: func(w http.ResponseWriter, r *http.Request, status int, reason error) {
|
||||
// // 在这里实现错误处理逻辑
|
||||
// g.Log().Errorf(r.Context(), "WebSocket upgrade error: %v", reason)
|
||||
// },
|
||||
//}
|
||||
//
|
||||
//// Echo WebSocket Echo 服务器处理器
|
||||
//// 路径: /ws
|
||||
//func (c *WebSocketController) Echo(r *ghttp.Request) {
|
||||
// // 将 HTTP 连接升级为 WebSocket
|
||||
// ws, err := wsUpgrader.Upgrade(r.Response.Writer, r.Request, nil)
|
||||
// if err != nil {
|
||||
// r.Response.Write(err.Error())
|
||||
// return
|
||||
// }
|
||||
// defer ws.Close()
|
||||
//
|
||||
// // 获取请求上下文用于日志记录
|
||||
// var ctx = r.Context()
|
||||
// logger := g.Log()
|
||||
//
|
||||
// // 消息处理循环
|
||||
// for {
|
||||
// // 读取传入的 WebSocket 消息
|
||||
// msgType, msg, err := ws.ReadMessage()
|
||||
// if err != nil {
|
||||
// break // 连接关闭或发生错误
|
||||
// }
|
||||
// // 记录接收到的消息
|
||||
// logger.Infof(ctx, "received message: %s", msg)
|
||||
// // 将消息回显给客户端
|
||||
// if err = ws.WriteMessage(msgType, msg); err != nil {
|
||||
// break // 写入消息时出错
|
||||
// }
|
||||
// }
|
||||
// // 记录连接关闭
|
||||
// logger.Info(ctx, "websocket connection closed")
|
||||
//}
|
||||
88
Backend/internal/controller/websocket/websocketV1.go
Normal file
88
Backend/internal/controller/websocket/websocketV1.go
Normal file
@@ -0,0 +1,88 @@
|
||||
package websocket
|
||||
|
||||
//
|
||||
//import (
|
||||
// "log"
|
||||
// "net/http"
|
||||
// "sync"
|
||||
//
|
||||
// "github.com/gogf/gf/v2/net/ghttp"
|
||||
// "github.com/gorilla/websocket"
|
||||
//)
|
||||
//
|
||||
//// 定义 WebSocket 升级器
|
||||
//var upgrader = websocket.Upgrader{
|
||||
// CheckOrigin: func(r *http.Request) bool {
|
||||
// return true
|
||||
// },
|
||||
//}
|
||||
//
|
||||
//// 存储客户端连接
|
||||
//var (
|
||||
// clients = make(map[*websocket.Conn]bool)
|
||||
// clientsMu sync.Mutex // 保护 clients map 的互斥锁
|
||||
// broadcast = make(chan string, 256) // 广播信息通道,带缓冲
|
||||
//)
|
||||
//
|
||||
//// 初始化广播处理(只启动一次)
|
||||
//var once sync.Once
|
||||
//
|
||||
//// HandlerConnection 处理websocket连接
|
||||
//func HandlerConnectionV1(r *ghttp.Request) {
|
||||
// // 启动广播处理 goroutine(只启动一次)
|
||||
// once.Do(func() {
|
||||
// go handleBroadcast()
|
||||
// })
|
||||
//
|
||||
// ws, err := upgrader.Upgrade(r.Response.Writer, r.Request, nil)
|
||||
// if err != nil {
|
||||
// log.Printf("upgrade error: %v", err)
|
||||
// return
|
||||
// }
|
||||
// defer func() {
|
||||
// clientsMu.Lock()
|
||||
// delete(clients, ws)
|
||||
// clientsMu.Unlock()
|
||||
// ws.Close()
|
||||
// }()
|
||||
//
|
||||
// // 注册新客户端
|
||||
// clientsMu.Lock()
|
||||
// clients[ws] = true
|
||||
// clientsMu.Unlock()
|
||||
//
|
||||
// for {
|
||||
// var message string
|
||||
// err := ws.ReadJSON(&message)
|
||||
// if err != nil {
|
||||
// log.Printf("read error: %v", err)
|
||||
// clientsMu.Lock()
|
||||
// delete(clients, ws)
|
||||
// clientsMu.Unlock()
|
||||
// break
|
||||
// }
|
||||
// // 将消息发送到广播通道
|
||||
// select {
|
||||
// case broadcast <- message:
|
||||
// default:
|
||||
// log.Printf("broadcast channel full, dropping message")
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//// 将广播通道给所有的用户
|
||||
//func handleBroadcast() {
|
||||
// for {
|
||||
// message := <-broadcast
|
||||
// clientsMu.Lock()
|
||||
// for client := range clients {
|
||||
// err := client.WriteJSON(message)
|
||||
// if err != nil {
|
||||
// log.Printf("write error: %v", err)
|
||||
// client.Close()
|
||||
// delete(clients, client)
|
||||
// }
|
||||
// }
|
||||
// clientsMu.Unlock()
|
||||
// }
|
||||
//}
|
||||
66
Backend/internal/controller/websocket/websocketV2.go
Normal file
66
Backend/internal/controller/websocket/websocketV2.go
Normal file
@@ -0,0 +1,66 @@
|
||||
package websocket
|
||||
|
||||
//
|
||||
//import (
|
||||
// "github.com/gorilla/websocket"
|
||||
// "log"
|
||||
// "net/http"
|
||||
// "sync"
|
||||
//)
|
||||
//
|
||||
//var upgraderv2 = websocket.Upgrader{CheckOrigin: func(r *http.Request) bool { return true }}
|
||||
//var clientsV2 = make(map[*websocket.Conn]bool) //
|
||||
//var mutex = sync.RWMutex{} // 读写锁 // 保护 clientsV2 并发访问
|
||||
//
|
||||
////var bufferPool = sync.Pool{
|
||||
//// New: func() interface{} {
|
||||
//// return make([]byte, 1024)
|
||||
//// },
|
||||
////}
|
||||
//
|
||||
//var bufferPool = sync.Pool{
|
||||
// New: func() interface{} {
|
||||
// return make([]byte, 1024)
|
||||
// },
|
||||
//}
|
||||
//
|
||||
//func readMessage(ws *websocket.Conn) ([]byte, error) {
|
||||
// buf := bufferPool.Get().([]byte)
|
||||
// defer bufferPool.Put(buf)
|
||||
// _, data, err := ws.ReadMessage()
|
||||
// return data, err
|
||||
//}
|
||||
//
|
||||
//func HandlerConnectionV2(w http.ResponseWriter, r *http.Request) {
|
||||
// ws, err := upgraderv2.Upgrade(w, r, nil)
|
||||
// if err != nil {
|
||||
// log.Printf("upgrade error: %v", err)
|
||||
// return
|
||||
// }
|
||||
// // 注册客户端
|
||||
// mutex.Lock()
|
||||
// clientsV2[ws] = true
|
||||
// mutex.Unlock()
|
||||
//
|
||||
// defer func() {
|
||||
// mutex.Lock()
|
||||
// delete(clientsV2, ws)
|
||||
// mutex.Unlock()
|
||||
// ws.Close()
|
||||
// }()
|
||||
//
|
||||
// for {
|
||||
// var message string
|
||||
// err := ws.ReadJSON(&message)
|
||||
// if err != nil {
|
||||
// log.Printf("read json error: %v", err)
|
||||
// return
|
||||
// }
|
||||
// // 广播消息(简化示例)
|
||||
// mutex.RLock()
|
||||
// for client := range clientsV2 {
|
||||
// client.WriteJSON(message)
|
||||
// }
|
||||
// mutex.RUnlock()
|
||||
// }
|
||||
//}
|
||||
Reference in New Issue
Block a user