繁体   English   中英

如何使用 ActiveMQ-Artemis 从 Java 程序向 Javascript STOMP 客户端发送消息?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM