82 lines
1.3 KiB
Go
82 lines
1.3 KiB
Go
|
package socketio
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"reflect"
|
||
|
)
|
||
|
|
||
|
const (
|
||
|
goSocketIOConnInterface = "Conn"
|
||
|
)
|
||
|
|
||
|
type funcHandler struct {
|
||
|
argTypes []reflect.Type
|
||
|
f reflect.Value
|
||
|
}
|
||
|
|
||
|
func (h *funcHandler) Call(args []reflect.Value) (ret []reflect.Value, err error) {
|
||
|
defer func() {
|
||
|
if r := recover(); r != nil {
|
||
|
var ok bool
|
||
|
err, ok = r.(error)
|
||
|
if !ok {
|
||
|
err = fmt.Errorf("event call error: %s", r)
|
||
|
}
|
||
|
}
|
||
|
}()
|
||
|
|
||
|
ret = h.f.Call(args)
|
||
|
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func newEventFunc(f interface{}) *funcHandler {
|
||
|
fv := reflect.ValueOf(f)
|
||
|
|
||
|
if fv.Kind() != reflect.Func {
|
||
|
panic("event handler must be a func.")
|
||
|
}
|
||
|
ft := fv.Type()
|
||
|
|
||
|
if ft.NumIn() < 1 || ft.In(0).Name() != goSocketIOConnInterface {
|
||
|
panic("handler function should be like func(socketio.Conn, ...)")
|
||
|
}
|
||
|
|
||
|
argTypes := make([]reflect.Type, ft.NumIn()-1)
|
||
|
for i := range argTypes {
|
||
|
argTypes[i] = ft.In(i + 1)
|
||
|
}
|
||
|
|
||
|
if len(argTypes) == 0 {
|
||
|
argTypes = nil
|
||
|
}
|
||
|
|
||
|
return &funcHandler{
|
||
|
argTypes: argTypes,
|
||
|
f: fv,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func newAckFunc(f interface{}) *funcHandler {
|
||
|
fv := reflect.ValueOf(f)
|
||
|
|
||
|
if fv.Kind() != reflect.Func {
|
||
|
panic("ack callback must be a func.")
|
||
|
}
|
||
|
|
||
|
ft := fv.Type()
|
||
|
argTypes := make([]reflect.Type, ft.NumIn())
|
||
|
|
||
|
for i := range argTypes {
|
||
|
argTypes[i] = ft.In(i)
|
||
|
}
|
||
|
if len(argTypes) == 0 {
|
||
|
argTypes = nil
|
||
|
}
|
||
|
|
||
|
return &funcHandler{
|
||
|
argTypes: argTypes,
|
||
|
f: fv,
|
||
|
}
|
||
|
}
|