// processMessage processes a single message and calls a handler or callback. func (c *Client) processMessage(data []byte) (msg *dnode.Message, fn interface{}, err error) { // Call error handler. defer func() { if err != nil { onError(err) } }() msg = &dnode.Message{} if err = json.Unmarshal(data, &msg); err != nil { return nil, nil, err } sender := func(id uint64, args []interface{}) error { // do not name the error variable to "err" here, it's a trap for // shadowing variables _, _, e := c.marshalAndSend(id, args) return e } // Replace function placeholders with real functions. if err := dnode.ParseCallbacks(msg, sender); err != nil { return nil, nil, err } // Find the handler function. Method may be string or integer. switch method := msg.Method.(type) { case float64: id := uint64(method) callback := c.scrubber.GetCallback(id) if callback == nil { err = dnode.CallbackNotFoundError{ ID: id, Args: msg.Arguments, } return nil, nil, err } return msg, callback, nil case string: m, ok := c.LocalKite.handlers[method] if !ok { err = dnode.MethodNotFoundError{ Method: method, Args: msg.Arguments, } return nil, nil, err } return msg, m, nil default: return nil, nil, fmt.Errorf("Method is not string or integer: %+v (%T)", msg.Method, msg.Method) } }
// processMessage processes a single message and calls a handler or callback. func (c *Client) processMessage(data []byte) (err error) { var ( ok bool msg dnode.Message m *Method ) // Call error handler. defer func() { if err != nil { onError(err) } }() if err := json.Unmarshal(data, &msg); err != nil { return err } sender := func(id uint64, args []interface{}) error { // do not name the error variable to "err" here, it's a trap for // shadowing variables _, errc := c.marshalAndSend(id, args) return errc } // Replace function placeholders with real functions. if err := dnode.ParseCallbacks(&msg, sender); err != nil { return err } // Find the handler function. Method may be string or integer. switch method := msg.Method.(type) { case float64: id := uint64(method) callback := c.scrubber.GetCallback(id) if callback == nil { err = dnode.CallbackNotFoundError{id, msg.Arguments} return err } c.runCallback(callback, msg.Arguments) case string: if m, ok = c.LocalKite.handlers[method]; !ok { err = dnode.MethodNotFoundError{method, msg.Arguments} return err } c.runMethod(m, msg.Arguments) default: return fmt.Errorf("Method is not string or integer: %+v (%T)", msg.Method, msg.Method) } return nil }