Spring boot 使用apache qpid通过amqpwss连接到azure服务总线端口443

Spring boot 使用apache qpid通过amqpwss连接到azure服务总线端口443,spring-boot,azureservicebus,amqp,qpid,Spring Boot,Azureservicebus,Amqp,Qpid,我正在尝试使用starter连接Azure服务总线(我知道在引擎盖下使用starter) 当我将连接字符串(amqphub.amqp10jms.remote url)设置为使用“amqps://”时,一切正常,一条hello world消息被发送到Azure队列,然后由应用程序检索和打印 但是,当我使用“amqpwss://[Endpoint]:443”连接字符串时,我收到一个异常 Caused by: io.netty.handler.codec.http.websocketx.WebSock

我正在尝试使用starter连接Azure服务总线(我知道在引擎盖下使用starter)

当我将连接字符串(amqphub.amqp10jms.remote url)设置为使用“amqps://”时,一切正常,一条hello world消息被发送到Azure队列,然后由应用程序检索和打印

但是,当我使用“amqpwss://[Endpoint]:443”连接字符串时,我收到一个异常

Caused by: io.netty.handler.codec.http.websocketx.WebSocketHandshakeException: Invalid handshake response getStatus: 400 This service does not support WebSocket connections.
我怀疑Azure服务总线不支持WebSocket连接

  • amqphub文档声称这是可能的:
  • 与apache quid文档一样:
  • 与服务总线文档“AMQP WebSockets绑定在TCP端口443上创建一个隧道,该端口相当于AMQP 5671连接”一样:
  • 如何从Spring Boot应用程序建立到Azure服务总线的amqpwss连接?(我想使用qpid,但我不受它的限制)


    这里的示例代码:

    在一次试图提高销售的支持尝试之后,再次查看文档,我再次证明,微软非常有兴趣拥抱并将用户锁定在他们的花园中

    除了长篇大论之外,连接到websockets端点的URL与常规AMQP端点不同

    amqps://[endpoint]
    
    要使用WebSocket进行连接,需要将协议替换为amqpwss,将端口替换为443

    amqpwss://[endpoint]:443
    
    但是,没有提到的是,您还必须指定路径
    /$servicebus/websocket

    amqpwss://[endpoint]:443/$servicebus/websocket
    

    我不知道你应该如何理解这一点。请证明我错了,并指出文档中截至2021-03-18的部分确实包含了这一点信息。无论如何,我是通过关于通过WebSocket从浏览器连接到azure service bus的SO问题发现的。

    ,而我相信Dragas的答案是正确的解决方案,我想如果它对任何人都有用的话,我会添加我所采用的方法

    我最终使用了Java库,因为我发现它依赖于他们自己的ApacheQpid扩展库。repo描述为“扩展Qpid-proton-j库,通过WebSocket与AMQP对话”…所以我认为这可以完成这项工作

    我使用

    订阅响应,通过网关将任何消息发送到我的Spring集成流中。我添加了一些可配置属性以在消息消费之间应用回退

       /**
         * Azure service bus listener.
         *
         * @param receiveClient   client
         * @param executorService executorService
         * @throws Exception If we cannot poll queue.
         */
        private void registerMessageHandlerOnClient(SubscriptionClient receiveClient, ExecutorService executorService) throws Exception {
            // register the RegisterMessageHandler callback
            receiveClient.registerMessageHandler(
                    new IMessageHandler() {
                        // callback invoked when the message handler loop has obtained a message
                        public CompletableFuture<Void> onMessageAsync(IMessage message) {
    
                            log.debug("Message received from azure, id: {}", message.getMessageId()); //TODO deprecation alternative
                            brokerGateway.send(message.getBody());
    
                            try {
                                Thread.sleep(backOff.toMillis());
                            } catch (InterruptedException e) {
                                log.error("Failed to apply azure backoff", e);
                            }
                            return CompletableFuture.completedFuture(null);
                        }
    
                        // callback invoked when the message handler has an exception to report
                        public void notifyException(Throwable throwable, ExceptionPhase exceptionPhase) {
                            log.error("Exception {}", exceptionPhase, throwable);
                        }
                    },
                    // 1 concurrent call, messages are auto-completed, auto-renew duration
                    new MessageHandlerOptions(1, false, Duration.ofMinutes(1)),
                    executorService);
    
        }
    
    /**
    *Azure服务总线侦听器。
    *
    *@param receiveClient客户端
    *@param executorService executorService
    *@如果无法轮询队列,则引发异常。
    */
    私有无效注册表MessageHandlerOnClient(SubscriptionClient receiveClient,ExecutorService ExecutorService)引发异常{
    //注册RegisterMessageHandler回调
    receiveClient.registerMessageHandler(
    新的IMessageHandler(){
    //当消息处理程序循环获得消息时调用回调
    公共CompletableFuture onMessageAsync(IMessage消息){
    log.debug(“从azure接收的消息,id:{}”,Message.getMessageId());//TODO弃用替代方案
    send(message.getBody());
    试一试{
    Thread.sleep(backOff.toMillis());
    }捕捉(中断异常e){
    日志错误(“未能应用azure回退”,e);
    }
    返回CompletableFuture.completedFuture(空);
    }
    //当消息处理程序有异常要报告时调用回调
    公共无效notifyException(可丢弃可丢弃,ExceptionPhase ExceptionPhase){
    错误(“Exception{}”,exceptionPhase,throwable);
    }
    },
    //1个并发呼叫,消息自动完成,自动续订持续时间
    新MessageHandlerOptions(1,false,持续时间为分钟(1)),
    执行人服务);
    }
    
    我想这就是我想要实现的目标:.Qpid JMS支持这一开箱即用的功能,您可能需要联系MS以获得支持有趣的事实:
    azure servicebus JMS:0.0.7
    不尊重传输类型标志,即使它为amqp提供了一个选项而不是WebSocket。哇,这当然不明显。谢谢!如果有任何用处,我有一个将我的解决方法添加到下面。
       /**
         * Azure service bus listener.
         *
         * @param receiveClient   client
         * @param executorService executorService
         * @throws Exception If we cannot poll queue.
         */
        private void registerMessageHandlerOnClient(SubscriptionClient receiveClient, ExecutorService executorService) throws Exception {
            // register the RegisterMessageHandler callback
            receiveClient.registerMessageHandler(
                    new IMessageHandler() {
                        // callback invoked when the message handler loop has obtained a message
                        public CompletableFuture<Void> onMessageAsync(IMessage message) {
    
                            log.debug("Message received from azure, id: {}", message.getMessageId()); //TODO deprecation alternative
                            brokerGateway.send(message.getBody());
    
                            try {
                                Thread.sleep(backOff.toMillis());
                            } catch (InterruptedException e) {
                                log.error("Failed to apply azure backoff", e);
                            }
                            return CompletableFuture.completedFuture(null);
                        }
    
                        // callback invoked when the message handler has an exception to report
                        public void notifyException(Throwable throwable, ExceptionPhase exceptionPhase) {
                            log.error("Exception {}", exceptionPhase, throwable);
                        }
                    },
                    // 1 concurrent call, messages are auto-completed, auto-renew duration
                    new MessageHandlerOptions(1, false, Duration.ofMinutes(1)),
                    executorService);
    
        }