封装的方法类

This commit is contained in:
Yun
2023-09-16 20:14:20 +08:00
commit 1bbc7db405
59 changed files with 3671 additions and 0 deletions
+115
View File
@@ -0,0 +1,115 @@
package more
import (
"sync"
uuid "github.com/satori/go.uuid"
)
// 同一个key对应多个连接
// 2023年6月29日13:45:25
// 场景:
// 1. 同时支持多个用户在线
// 1. 一个用户对应多个连接
// 2. 在其中一个用户连接中发送消息,同用户其他连接也能收到
type connPool struct {
pool map[string]map[string]PoolValue
idx map[string]string // 索引
mu sync.RWMutex
}
type PoolValue interface {
Close() error
}
// 初始化连接池
func NewConnPool() *connPool {
return &connPool{
pool: make(map[string]map[string]PoolValue),
idx: make(map[string]string),
mu: sync.RWMutex{},
}
}
// 添加连接, 返回connId
func (c *connPool) Store(key string, value PoolValue) string {
c.mu.Lock()
defer c.mu.Unlock()
val, _ := c.pool[key]
connId := uuid.NewV4().String()
val[connId] = value
c.pool[key] = val
c.idx[connId] = key
return connId
}
// 获取一个用户的所有连接
func (c *connPool) LoadByKey(key string) (conns map[string]PoolValue, ok bool) {
c.mu.RLock()
defer c.mu.RUnlock()
valMap, ok := c.pool[key]
return valMap, ok
}
// 根据连接ID获取连接
func (c *connPool) LoadByConnId(connId string) (*PoolValue, bool) {
c.mu.RLock()
defer c.mu.Unlock()
key, ok := c.idx[connId]
if !ok {
return nil, false
}
valMap, ok := c.pool[key]
if !ok {
return nil, false
}
val, ok := valMap[connId]
if !ok {
return nil, false
}
return &val, true
}
// 关闭连接
func (c *connPool) Close(connId string) {
c.mu.Lock()
defer c.mu.Unlock()
key, ok := c.idx[connId]
if !ok {
return
}
valMap, ok := c.pool[key]
if !ok {
return
}
val, ok := valMap[connId]
if !ok {
return
}
delete(valMap, connId)
// 异步关闭
go val.Close()
}
// 遍历所有的连接
func (c *connPool) Range(f func(key string, connId string, values PoolValue)) {
c.mu.RLock()
defer c.mu.Unlock()
for key, val := range c.pool {
val := val
for keyPoo, valPoo := range val {
go f(key, keyPoo, valPoo)
}
}
}
+57
View File
@@ -0,0 +1,57 @@
package connPoolx
import (
"errors"
"sync"
)
// 连接池
// 核心思想:连接放在这里面统一管理,所有的新建与删除需要外部操作
// 适用场景:每一个key对应一个val
type connPool struct {
pool sync.Map
}
type PoolValue interface {
Close() error
}
func NewConnPool() *connPool {
return &connPool{}
}
// 同名将覆盖
func (c *connPool) Store(key string, value PoolValue) {
c.pool.Store(key, value)
}
func (c *connPool) Load(key string) (value PoolValue, ok bool) {
val, ok := c.pool.Load(key)
if !ok {
return nil, false
}
value, ok = val.(PoolValue)
if !ok {
return nil, false
}
return value, true
}
func (c *connPool) Close(key string) error {
val, ok := c.pool.LoadAndDelete(key)
if ok {
value, ok := val.(PoolValue)
if !ok {
return errors.New("解析异常")
}
return value.Close()
}
return nil
}
func (c *connPool) Range(f func(key any, value any) bool) {
c.pool.Range(f)
}