コード例 #1
0
func (p RpcMessageReceiver) handleRpc(args []interface{}, kwargs map[string]interface{}) *gowamp.CallResult {
	defer utils.Recover()

	var msg messaging.Message

	if msgStr, ok := args[0].(string); ok {
		err := msg.FromString(msgStr)
		if err != nil {
			return p.makeErrorResult(err)
		}
	} else {
		err := models.Convert(args[0], &msg)
		if err != nil {
			return p.makeErrorResult(err)
		}
	}

	log.Info("RPC message received:", msg)
	res, err := p.MessageProcessor.Process(msg)
	if err != nil {
		return p.makeErrorResult(err)
	}

	return p.makeResult(res)
}
コード例 #2
0
func (p WsMessageReceiver) handleSubscribe(im interceptorMessage, msg *gowamp.Subscribe) {
	opts := models.SubscribeOptions{}
	err := models.Convert(msg.Options, &opts)
	if err != nil {
		log.Error(err)
		return
	}

	topic := fmt.Sprintf("%v", msg.Topic)
	topicArguments := strings.Split(topic, ".")

	opts.Topic = topic
	if opts.IsSpecial() {
		baseTopic := messaging.BuildTopicArbitrary(topicArguments[:len(topicArguments)-1]...)
		opts.BaseTopic = baseTopic
	} else {
		opts.BaseTopic = topic
	}

	log.Info("Listening for changefeed:", opts)
	d := db.NewDbService()
	newValuesChan := make(chan map[string]interface{})

	//for create and delete we want to listen for changes for the whole collection, for update only for the specific item
	if opts.Operation == messaging.OP_CREATE || opts.Operation == messaging.OP_DELETE {
		err = d.Changes(opts.AppId, opts.Type, opts.Filter, newValuesChan)
	} else if opts.Operation == messaging.OP_UPDATE {
		opts.ItemId = topicArguments[len(topicArguments)-1]
		err = d.ChangesId(opts.ItemId, newValuesChan)
	}

	if err != nil {
		log.Error(err)
		return
	}

	messageBuilder := messaging.GetMessageBuilder()
	go func() {
		leaveChan := make(chan interface{})
		p.broadcaster.Subscribe(leaveChan)

		for {
			select {
			case val := <-newValuesChan:
				p.processDatabaseUpdate(val, &messageBuilder, opts)
			case leaveVal := <-leaveChan:
				sessionId := leaveVal.(gowamp.ID)
				if im.sess.Id == sessionId {
					//TODO: newValuesChan seems to be automatically closed by the rethinkdb driver
					//investigate whether we need to do something else

					_, leaveChanOpened := <-leaveChan
					if leaveChanOpened {
						close(leaveChan)
					}

					p.broadcaster.Remove(leaveChan)
					return
				}
			}
		}
	}()
}