[英]How do I send messages from Java program to a Javascript STOMP client using ActiveMQ-Artemis?
我正在尝试在 Java 进程和浏览器 UI 之间来回通信。 为此,我在 Artemis 中配置了一个多播地址。 来自 Java 进程的消息不会发送到使用 StompJS 实现的浏览器订阅者。
为了测试,我用 Java 和 Javascript 编写了一个 Hello World 类型的程序,以尽可能简化问题。 两个程序都会在该地址上启动消费者,然后向该地址发送 100 条消息。 消费者只是记录他们收到了消息。
Java 程序接收它产生的所有消息和 Javascript 程序产生的所有消息。 Javascript 程序接收它产生的所有消息,但没有接收 Java 程序产生的任何消息。
当我使用 Artemis 控制台查看 STOMP 客户端创建的队列时,它显示添加了 200 条消息,100 条已确认,100 条卡在传递中。
如果我使用 Artemis 控制台向该地址发送消息,Java 和 Javascript 程序都会收到该消息。
有什么想法我在这里做错了吗?
Javascript程序
import { Client } from "@stomp/stompjs"
let client;
export function testStomp() {
client = new Client();
client.brokerURL = "ws://messaging-host:7961";
client.onConnect = handleConnected;
client.activate();
}
function handleConnected() {
client.subscribe("broadcastMessage", message => console.log(message.body));
const message = { destination: "broadcastMessage" };
for (let i = 0; i < 100; i++) {
message.body = "Message from javascript " + i;
client.publish(message);
}
}
Java程序:
package com.whatever;
import org.apache.activemq.artemis.api.core.*;
import org.apache.activemq.artemis.api.core.client.*;
import java.util.UUID;
public class TestArtemis {
public static void main(String[] args) throws Exception {
String url = "tcp://messaging-host:7961";
ServerLocator serverLocator = ActiveMQClient.createServerLocator(url);
ClientSession session = serverLocator.createSessionFactory().createSession();
startConsumer(session);
ClientProducer producer = session.createProducer();
for (int i = 0; i < 100; i++) {
String payload = "Message from java " + i;
ClientMessage message = session.createMessage(false);
message.getBodyBuffer().writeBytes(payload.getBytes());
producer.send("broadcastMessage", message);
Thread.sleep(1000);
}
}
private static void startConsumer(ClientSession session) throws Exception{
session.start();
String queueName = UUID.randomUUID().toString();
session.createQueue(new QueueConfiguration(queueName)
.setAddress("broadcastMessage")
.setDurable(false)
.setRoutingType(RoutingType.MULTICAST)
.setTemporary(true));
ClientConsumer consumer = session.createConsumer(queueName);
consumer.setMessageHandler(message -> {
byte[] bytes = new byte[message.getBodyBuffer().readableBytes()];
message.getDataBuffer().readBytes(bytes);
System.out.println("Received " + new String(bytes));
});
}
}
ActiveMQ Artemis 使用content-length
标头来检测 STOMP 消息类型是二进制还是文本。
要使用文本 STOMP 消息类型,Javascript 程序必须跳过content-length
标头,Java 程序必须生成文本类型的消息,即
Javascript 程序更改:
const message = { destination: "broadcastMessage", skipContentLengthHeader: true };
Java程序:
ClientMessage message = session.createMessage(Message.TEXT_TYPE, false);
message.getBodyBuffer().writeNullableSimpleString(SimpleString.toSimpleString(payload));
要使用二进制 STOMP 消息类型,Java 程序必须生成带有content-length
标头的消息,即
String payload = "Message from java " + i;
byte[] payloadBytes = payload.getBytes();
ClientMessage message = session.createMessage(false);
message.putIntProperty("content-length", payloadBytes.length);
message.getBodyBuffer().writeBytes(payloadBytes);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.