func (cls *ClientManager) remove(conn int) {
	cls.Lock()
	delete(cls.frame, conn)
	delete(cls.frames, conn)
	cls.all, _ = ints.Remove(cls.all, conn)
	ctx, ok := cls.ctx[conn]
	if ok {
		var uid uint64
		v := ctx.Value(CtxKeyUID)
		if v != nil {
			uid, _ = v.(uint64)
		}
		delete(cls.ctx, conn)
		if uid > 0 {
			conns, ok := cls.conns[uid]
			if ok {
				conns, _ = ints.Remove(conns, conn)
				if len(conns) == 0 {
					delete(cls.conns, uid)
				} else {
					cls.conns[uid] = conns
				}
			}
		}
	}
	cls.Unlock()
}
remove a connection from list of clients.
package websocket
import (
	"context"
	"sync"
	"github.com/shuLhan/share/lib/ints"
)
type ClientManager struct {
	sync.Mutex
	all []int
	conns map[uint64][]int
	ctx map[int]context.Context
	frame map[int]*Frame
	frames map[int]*Frames
}
func newClientManager() *ClientManager {
	return &ClientManager{
		conns:  make(map[uint64][]int),
		ctx:    make(map[int]context.Context),
		frame:  make(map[int]*Frame),
		frames: make(map[int]*Frames),
	}
}
func (cls *ClientManager) All() (conns []int) {
	cls.Lock()
	if len(cls.all) > 0 {
		conns = make([]int, len(cls.all))
		copy(conns, cls.all)
	}
	cls.Unlock()
	return
}
func (cls *ClientManager) finFrames(conn int, last *Frame) (f *Frame) {
	cls.Lock()
	frames, ok := cls.frames[conn]
	if !ok {
		cls.Unlock()
		return last
	}
	f = frames.fin(last)
	delete(cls.frames, conn)
	delete(cls.frame, conn)
	cls.Unlock()
	return
}
func (cls *ClientManager) Conns(uid uint64) (conns []int) {
	cls.Lock()
	conns = cls.conns[uid]
	cls.Unlock()
	return
}
func (cls *ClientManager) Context(conn int) (ctx context.Context) {
	cls.Lock()
	ctx = cls.ctx[conn]
	cls.Unlock()
	return
}
func (cls *ClientManager) getFrame(conn int) (frame *Frame, ok bool) {
	cls.Lock()
	frame, ok = cls.frame[conn]
	cls.Unlock()
	return
}
func (cls *ClientManager) getFrames(conn int) (frames *Frames, ok bool) {
	cls.Lock()
	frames, ok = cls.frames[conn]
	cls.Unlock()
	return
}
func (cls *ClientManager) setFrame(conn int, frame *Frame) {
	cls.Lock()
	if frame == nil {
		delete(cls.frame, conn)
	} else {
		cls.frame[conn] = frame
	}
	cls.Unlock()
}
func (cls *ClientManager) setFrames(conn int, frames *Frames) {
	cls.Lock()
	if frames == nil {
		delete(cls.frames, conn)
	} else {
		cls.frames[conn] = frames
	}
	cls.Unlock()
}
func (cls *ClientManager) add(ctx context.Context, conn int) {
	var uid uint64
	cls.remove(conn)
	cls.Lock()
	if !ints.IsExist(cls.all, conn) {
		cls.all = append(cls.all, conn)
	}
	cls.ctx[conn] = ctx
	v := ctx.Value(CtxKeyUID)
	if v != nil {
		uid, _ = v.(uint64)
	}
	if uid > 0 {
		conns, ok := cls.conns[uid]
		if !ok {
			conns = make([]int, 0, 1)
		}
		conns = append(conns, conn)
		cls.conns[uid] = conns
	}
	cls.Unlock()
}