我在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)