gosocketio/vendor/github.com/googollee/go-socket.io/namespace_handler.go

114 lines
2.4 KiB
Go
Raw Normal View History

2023-11-30 17:38:20 +08:00
package socketio
import (
"errors"
"reflect"
"sync"
"github.com/googollee/go-socket.io/parser"
)
type namespaceHandler struct {
broadcast Broadcast
events map[string]*funcHandler
eventsLock sync.RWMutex
onConnect func(conn Conn) error
onDisconnect func(conn Conn, msg string)
onError func(conn Conn, err error)
}
func newNamespaceHandler(nsp string, adapterOpts *RedisAdapterOptions) *namespaceHandler {
var broadcast Broadcast
if adapterOpts == nil {
broadcast = newBroadcast()
} else {
broadcast, _ = newRedisBroadcast(nsp, adapterOpts)
}
return &namespaceHandler{
broadcast: broadcast,
events: make(map[string]*funcHandler),
}
}
func (nh *namespaceHandler) OnConnect(f func(Conn) error) {
nh.onConnect = f
}
func (nh *namespaceHandler) OnDisconnect(f func(Conn, string)) {
nh.onDisconnect = f
}
func (nh *namespaceHandler) OnError(f func(Conn, error)) {
nh.onError = f
}
func (nh *namespaceHandler) OnEvent(event string, f interface{}) {
nh.eventsLock.Lock()
defer nh.eventsLock.Unlock()
nh.events[event] = newEventFunc(f)
}
func (nh *namespaceHandler) getEventTypes(event string) []reflect.Type {
nh.eventsLock.RLock()
namespaceHandler := nh.events[event]
nh.eventsLock.RUnlock()
if namespaceHandler != nil {
return namespaceHandler.argTypes
}
return nil
}
func (nh *namespaceHandler) dispatch(conn Conn, header parser.Header, args ...reflect.Value) ([]reflect.Value, error) {
switch header.Type {
case parser.Connect:
if nh.onConnect != nil {
return nil, nh.onConnect(conn)
}
return nil, nil
case parser.Disconnect:
if nh.onDisconnect != nil {
nh.onDisconnect(conn, getDispatchMessage(args...))
}
return nil, nil
case parser.Error:
if nh.onError != nil {
msg := getDispatchMessage(args...)
if msg == "" {
msg = "parser error dispatch"
}
nh.onError(conn, errors.New(msg))
}
}
return nil, parser.ErrInvalidPacketType
}
func (nh *namespaceHandler) dispatchEvent(conn Conn, event string, args ...reflect.Value) ([]reflect.Value, error) {
nh.eventsLock.RLock()
namespaceHandler := nh.events[event]
nh.eventsLock.RUnlock()
if namespaceHandler == nil {
return nil, nil
}
return namespaceHandler.Call(append([]reflect.Value{reflect.ValueOf(conn)}, args...))
}
func getDispatchMessage(args ...reflect.Value) string {
var msg string
if len(args) > 0 {
msg = args[0].Interface().(string)
}
return msg
}