Vert.x RabbitMQ无限循环问题

时间:2018-07-03 19:27:25

标签: rabbitmq vert.x

我在JavaScript项目和服务器端使用的是vertx3-eventbus-client 3.5.2 ,我使用的是相同版本。我想当用户登录服务器时为此用户创建队列。当我发送消息时,该队列如果用户已经登录,则用户应显示此消息。如果用户在重新联机时未登录,则应显示消息。

当我在浏览器上登录项目时,我从Rabbitmq Web面板向用户注册的队列名称发送消息,一切正常。但是,当我关闭浏览器选项卡的套接字连接时(正常)关闭,那么我的未注册事件总线地址是此代码vertx.eventBus().consumer<JsonObject>(message.queueEventBusAdress).unregister。然后,当我再次从Rabbitmq Web面板向注销用户队列名发送消息后,我得到了一个错误(NO_HANDLERS,-1) No handlers for address exampleUser,因此该消息已从消息代理处等待。然后我认为我必须添加ack-nack控制器。当我从Rabbitmq发送消息时,如果用户收到消息客户端答复服务器“ true”,则我发送ack消息,否则我发送n-ack消息作为重新排队消息。但是这次我进入无限循环...创建用户套接字连接后如何重新注册basicConsumer?

日志:

starting from delivery tag 1
...
...
8989 delivery tag for n-ack message success
Eventbus consumer exampleUser Deliverytag: 8990
Data consumed! hi exampleUser
Can't send No handlers for address exampleUser
8990 delivery tag for n-ack message success
Eventbus consumer exampleUser Deliverytag: 8991
Data consumed! hi exampleUser
Can't send No handlers for address exampleUser
8991 delivery tag for n-ack message success
Eventbus consumer exampleUser Deliverytag: 8992
Data consumed! hi exampleUser
Can't send No handlers for address exampleUser

客户端

eventBus.registerHandler(user.id, "", (err: Error, msj: any) => {
  if (!err) {
    console.log(msj.body);
    if (msj.reply) {
        msj.reply(true);
    } else {
        console.error("I can't find reply function.")
    }
  } else {
    console.error("On error occured in message handler", err)
  }
});

服务器端:

private var handler: SockJSHandler

init {
    val sockJsOptions = SockJSHandlerOptions()
    val bridgeOptions = BridgeOptions()
            .addInboundPermitted(PermittedOptions().setAddressRegex(".*"))
            .addOutboundPermitted(PermittedOptions().setAddressRegex(".*"))

    handler = SockJSHandler.create(vertx, sockJsOptions)
    handler.bridge(bridgeOptions) {
        val socket  = it.socket()
        when (it.type()) {
            SOCKET_CREATED -> {
                                println("Created socket");
                socket.webUser().socketCreated()
            }
            SOCKET_CLOSED  -> {
                                println("Closed socket");
                socket.webUser().socketClosed()
            }
        }
        it.complete(true)
    }

    router.route("/${"/rabbitmq/}/*").handler {
        try {
            handler.handle(it)
        } catch (e: Exception) {}
    }
}

fun User.socketCreated() {
    val principal = principal()
    vertx.eventBus().send("CREATE", JsonObject().put("USERID", principal.getString("userId")))
}

fun User.socketClosed() {
    val principal = principal()
    vertx.eventBus().send("CLOSE", JsonObject().put("USERID", principal.getString("userId")))
}


private fun start(client: RabbitMQClient) {
    vertx.eventBus().consumer<JsonObject>(CREATE) {
        val message = it.getMessageJSON() ?: return@consumer

        client.queueDeclare(message.queueName, true, false, false) {
            if (it.succeeded()) {
                println("Eventbus consumer registered --${message.queueEventBusAdress}")

                vertx.eventBus().consumer<JsonObject>(message.queueEventBusAdress) {
                    val rabbitMQJson = it.body()
                    val deliveryTag = rabbitMQJson.getLong("deliveryTag")

                    if (rabbitMQJson != null && rabbitMQJson.containsKey("body")) {
                        val data = rabbitMQJson.getString("body")
                        vertx.eventBus().send<Boolean>(message.queueClientRegisteredHandlerAdress, data) {
                            if (it.succeeded()) {
                                println("Message sended-- ${message.userId}")

                                vertx.runOnContext {
                                    client.basicAck(deliveryTag, false) {
                                        if (it.succeeded()) {
                                            println("$deliveryTag delivery tag for ack message success.")
                                        } else {
                                            it.cause().printStackTrace()
                                            println("$deliveryTag delivery tag for ack message failed -- ${it.cause().message}")
                                        }
                                    }
                                }
                            } else {
                                vertx.runOnContext {
                                    client.basicNack(deliveryTag, false, true) {
                                        if (it.succeeded()) {
                                            println("$deliveryTag delivery tag for n-ack message success.")
                                        } else {
                                            it.cause().printStackTrace()
                                            println("$deliveryTag delivery tag for n-ack message failed -- ${it.cause().message}")
                                        }
                                    }
                                }

                                it.cause().printStackTrace()
                                println("Can't send ${it.cause().message}")
                            }
                        }
                    } else println("Json null!")
                }

                client.basicConsume(message.queueName, message.queueEventBusAdress, false) {
                    if (it.succeeded()) {
                        println("Consume registered!")
                    } else {
                        log.error("Basic consume failed ${message.userId}", it.cause())
                    }
                }
            } else log.error("Queue creation failed!")
        }
    }

    vertx.eventBus().consumer<JsonObject>("CLOSE") {
        val message = it.getMessageJSON() ?: return@consumer

        vertx.eventBus().consumer<JsonObject>(message.queueEventBusAdress).unregister {
            if (it.succeeded()) {
                println("${message.userId} consumer unregistered!")
            } else {
                it.cause().printStackTrace()
            }
        }
    }

}

@Suppress("UnnecessaryVariable")
private fun Message<JsonObject>.getMessageJSON(): Message? {
    val obj = body()
    if (obj.containsKey("USERID")) {
        val userId = obj.getString("userId")
        val queueName ="rabbitmq.user." + userId
        val queueEventBusAdress = queueName
        val queueClientRegisteredHandlerAdress = userId

        return Message(
                        userId = userId,
                        queueName = queueName,
                        queueEventBusAdress = queueEventBusAdress,
                        queueClientRegisteredHandlerAdress = queueClientRegisteredHandlerAdress
                        )
    }

    return null
}

inner class Message(
        val userId: String,
        val queueName: String,
        val queueEventBusAdress: String,
        val queueClientRegisteredHandlerAdress: String)

0 个答案:

没有答案