增加群组广播
This commit is contained in:
@@ -3,6 +3,8 @@ package websocket
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/ayflying/utility_go/pkg/aycache"
|
||||||
|
"github.com/ayflying/utility_go/tools"
|
||||||
"github.com/gogf/gf/v2/container/gmap"
|
"github.com/gogf/gf/v2/container/gmap"
|
||||||
"github.com/gogf/gf/v2/encoding/gjson"
|
"github.com/gogf/gf/v2/encoding/gjson"
|
||||||
"github.com/gogf/gf/v2/frame/g"
|
"github.com/gogf/gf/v2/frame/g"
|
||||||
@@ -10,10 +12,10 @@ import (
|
|||||||
"github.com/gogf/gf/v2/os/gctx"
|
"github.com/gogf/gf/v2/os/gctx"
|
||||||
"github.com/gogf/gf/v2/os/glog"
|
"github.com/gogf/gf/v2/os/glog"
|
||||||
"github.com/gogf/gf/v2/util/guid"
|
"github.com/gogf/gf/v2/util/guid"
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
"google.golang.org/protobuf/proto"
|
"google.golang.org/protobuf/proto"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SocketV1 struct {
|
type SocketV1 struct {
|
||||||
@@ -24,16 +26,17 @@ var (
|
|||||||
//ctx = gctx.New()
|
//ctx = gctx.New()
|
||||||
//Conn map[uuid.UUID]*WebsocketData
|
//Conn map[uuid.UUID]*WebsocketData
|
||||||
lock sync.Mutex
|
lock sync.Mutex
|
||||||
|
cache = aycache.New("redis")
|
||||||
m = gmap.NewHashMap(true)
|
m = gmap.NewHashMap(true)
|
||||||
)
|
)
|
||||||
|
|
||||||
type WebsocketData struct {
|
type WebsocketData struct {
|
||||||
Ws *websocket.Conn
|
Ws *websocket.Conn `json:"ws" dc:"websocket连接池"`
|
||||||
Uuid string
|
Uuid string `json:"uuid" dc:"用户唯一标识"`
|
||||||
Uid int64
|
Uid int64 `json:"uid" dc:"用户编号"`
|
||||||
Ctx context.Context
|
Groups []string `json:"groups" dc:"群组"`
|
||||||
RoomId int
|
Ctx context.Context `json:"ctx" dc:""`
|
||||||
|
RoomId int `json:"roomId" dc:"房间编号"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewV1() *SocketV1 {
|
func NewV1() *SocketV1 {
|
||||||
@@ -90,6 +93,8 @@ func (s *SocketV1) OnConnect(ctx context.Context, conn *websocket.Conn) {
|
|||||||
Uuid: id,
|
Uuid: id,
|
||||||
Ws: conn,
|
Ws: conn,
|
||||||
Ctx: ctx,
|
Ctx: ctx,
|
||||||
|
Groups: make([]string, 0),
|
||||||
|
RoomId: -1,
|
||||||
}
|
}
|
||||||
m.Set(id, data)
|
m.Set(id, data)
|
||||||
|
|
||||||
@@ -205,17 +210,18 @@ func (s *SocketV1) Uid2Uuid(uid int64) (uuid string) {
|
|||||||
// @receiver s
|
// @receiver s
|
||||||
// @param uid
|
// @param uid
|
||||||
// @param data
|
// @param data
|
||||||
func (s *SocketV1) SendUuid(cmd int32, id uuid.UUID, req proto.Message) {
|
func (s *SocketV1) SendUuid(cmd int32, uuidStr string, req proto.Message) {
|
||||||
if !m.Contains(id) {
|
if !m.Contains(uuidStr) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
//格式化数据
|
||||||
var data, err = proto.Marshal(req)
|
var data, err = proto.Marshal(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
g.Log().Error(gctx.New(), err)
|
g.Log().Error(gctx.New(), err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
conn := m.Get(id).(*WebsocketData)
|
conn := m.Get(uuidStr).(*WebsocketData)
|
||||||
|
|
||||||
//前置方法
|
//前置方法
|
||||||
|
|
||||||
@@ -223,9 +229,7 @@ func (s *SocketV1) SendUuid(cmd int32, id uuid.UUID, req proto.Message) {
|
|||||||
temp := v(cmd, data, 0, "")
|
temp := v(cmd, data, 0, "")
|
||||||
data, _ = proto.Marshal(temp)
|
data, _ = proto.Marshal(temp)
|
||||||
}
|
}
|
||||||
|
|
||||||
conn.Ws.WriteMessage(s.Type, data)
|
conn.Ws.WriteMessage(s.Type, data)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,26 +246,7 @@ func (s *SocketV1) Send(cmd int32, uid int64, req proto.Message) {
|
|||||||
if uuid == "" {
|
if uuid == "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !m.Contains(uuid) {
|
s.SendUuid(cmd, uuid, req)
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
//格式化数据
|
|
||||||
var data, err = proto.Marshal(req)
|
|
||||||
if err != nil {
|
|
||||||
g.Log().Error(gctx.New(), err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
conn := m.Get(uuid).(*WebsocketData)
|
|
||||||
|
|
||||||
//前置方法
|
|
||||||
|
|
||||||
for _, v := range Byte2Pb {
|
|
||||||
temp := v(cmd, data, 0, "")
|
|
||||||
data, _ = proto.Marshal(temp)
|
|
||||||
}
|
|
||||||
conn.Ws.WriteMessage(s.Type, data)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -287,6 +272,47 @@ func (s *SocketV1) SendAll(cmd int32, req proto.Message) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//加入群组
|
||||||
|
func (s *SocketV1) JoinGroup(conn *WebsocketData, group string) {
|
||||||
|
conn.Groups = append(conn.Groups, group)
|
||||||
|
cacheKey := "websocket:group:" + group
|
||||||
|
get, _ := aycache.New("redis").Get(conn.Ctx, cacheKey)
|
||||||
|
var list = make(map[int64]string)
|
||||||
|
if !get.IsNil() {
|
||||||
|
get.Scan(&list)
|
||||||
|
}
|
||||||
|
list[conn.Uid] = conn.Uuid
|
||||||
|
cache.Set(conn.Ctx, cacheKey, list, time.Hour*24*7)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 退出群组
|
||||||
|
func (s *SocketV1) LeaveGroup(conn *WebsocketData, group string) {
|
||||||
|
conn.Groups = tools.RemoveSlice[string](conn.Groups, group)
|
||||||
|
cacheKey := "websocket:group:" + group
|
||||||
|
get, _ := cache.Get(conn.Ctx, cacheKey)
|
||||||
|
var list = make(map[int64]string)
|
||||||
|
if !get.IsNil() {
|
||||||
|
get.Scan(&list)
|
||||||
|
}
|
||||||
|
delete(list, conn.Uid)
|
||||||
|
cache.Set(conn.Ctx, cacheKey, list, time.Hour*24*7)
|
||||||
|
}
|
||||||
|
|
||||||
|
//群组广播
|
||||||
|
func (s *SocketV1) SendGroup(cmd int32, group string, req proto.Message) {
|
||||||
|
cacheKey := "websocket:group:" + group
|
||||||
|
get, _ := cache.Get(gctx.New(), cacheKey)
|
||||||
|
var list = make(map[int64]string)
|
||||||
|
if !get.IsNil() {
|
||||||
|
get.Scan(&list)
|
||||||
|
}
|
||||||
|
for uid, v := range list {
|
||||||
|
if m.Contains(v) {
|
||||||
|
s.Send(cmd, uid, req)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// OnClose
|
// OnClose
|
||||||
//
|
//
|
||||||
// @Description:
|
// @Description:
|
||||||
@@ -303,6 +329,9 @@ func (s *SocketV1) OnClose(conn *WebsocketData) {
|
|||||||
uid := conn.Uid
|
uid := conn.Uid
|
||||||
if uid > 0 {
|
if uid > 0 {
|
||||||
s.UnBindUid(uid)
|
s.UnBindUid(uid)
|
||||||
|
for _, v := range conn.Groups {
|
||||||
|
s.LeaveGroup(conn, v)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 可能的后续操作:
|
// 可能的后续操作:
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ func (m *tools) Items2Map(items [][]int64) (list map[int64]int64) {
|
|||||||
// 该函数通过遍历切片,从后向前检查每个元素,如果找到与指定值相等的元素,则将其从切片中移除。
|
// 该函数通过遍历切片,从后向前检查每个元素,如果找到与指定值相等的元素,则将其从切片中移除。
|
||||||
// 这种从后向前的遍历方法可以避免因移除元素而导致的数组重新排列带来的额外计算。
|
// 这种从后向前的遍历方法可以避免因移除元素而导致的数组重新排列带来的额外计算。
|
||||||
// RemoveSlice 删除切片中的某个值
|
// RemoveSlice 删除切片中的某个值
|
||||||
func RemoveSlice[t Number](slice []t, value ...t) []t {
|
func RemoveSlice[t Any](slice []t, value ...t) []t {
|
||||||
// 从后向前遍历切片
|
// 从后向前遍历切片
|
||||||
for i := len(slice) - 1; i >= 0; i-- {
|
for i := len(slice) - 1; i >= 0; i-- {
|
||||||
// 检查当前元素是否等于需要移除的值
|
// 检查当前元素是否等于需要移除的值
|
||||||
@@ -149,7 +149,7 @@ func RemoveSlice[t Number](slice []t, value ...t) []t {
|
|||||||
// @param value 需要查找的值
|
// @param value 需要查找的值
|
||||||
// @param array 进行查找的切片
|
// @param array 进行查找的切片
|
||||||
// @return bool 返回是否存在
|
// @return bool 返回是否存在
|
||||||
func InArray[t Number](array []t, value t) bool {
|
func InArray[t Any](array []t, value t) bool {
|
||||||
for _, v := range array {
|
for _, v := range array {
|
||||||
if v == value {
|
if v == value {
|
||||||
return true
|
return true
|
||||||
|
|||||||
Reference in New Issue
Block a user