This commit is contained in:
2026-01-18 18:20:40 +08:00
commit 20ed44aa74
178 changed files with 13789 additions and 0 deletions

View 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()
}
}

View 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")
//}

View 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()
// }
//}

View 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()
// }
//}