You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Solace JS API发送消息时遇WaitingForDNS状态错误

问题描述

调用Solace JavaScript API发送消息到主题队列时,返回错误:

OperationError: Cannot perform operation SEND while in state WaitingForDNS

目标URL可正常ping通且能解析为IP地址,认为该错误提示存在误导性。

代码场景

使用TypeScript编写,核心逻辑为:检查会话是否已创建,未创建则通过Solace工厂创建会话并调用connect(),因未捕获到连接错误便认为会话已连接,但调用send()时仍提示会话处于WaitingForDNS状态。代码片段如下(已移除无关日志):

class TopicPublisher {
    private getSession() {
        if (this.session == null) {
            try {
                this.log('Creating session for url=' + this.hosturl+' vpn='+this.vpn+' username='+this.username);
                this.session = this.solace.SolclientFactory.createSession({
                    // solace.SessionProperties
                    url: this.hosturl,
                    vpnName: this.vpn,
                    userName: this.username,
                    password: this.pass,
                });

                // Set session event handlers
                try {
                    this.session.connect();
                } catch(error : any) {
                    this.log('Could not make connection to existing session. Error: '+error.toString());
                    this.session = null;
                }


            } catch (error: any) {
                this.log(error.toString());
            }

        }
        return this.session;

    }

    public publish(messageContent: any) {
        var solaceMessage = this.getSolaceMessage(messageContent);
        this.log('Publishing message "' + messageContent + '" to topic "' + this.topicName + '"...');
        try {
            // *************************
            // This is where SEND fails 
            // *************************
            this.getSession().send(solaceMessage);
            this.log('Message published.');
        } catch (error: any) {
            this.log(error.toString());
        }

    };
}
问题分析与解决方案

核心原因

Solace的connect()方法是异步操作,调用后不会立即完成连接流程,仅触发连接请求。此时会话仍处于WaitingForDNS或其他中间状态,直接调用send()必然失败。代码中仅通过try/catch捕获connect()的同步异常,但异步的连接状态变化不会被该try/catch捕获,导致错误判断连接已成功。

另外,错误提示WaitingForDNS并不一定真的是DNS解析问题,而是会话还未完成初始化流程(包括DNS解析、TCP连接、会话认证等步骤),此时会话状态尚未进入Connected。

解决方案

1. 监听会话状态事件,确保连接完成后再发送消息

必须通过Solace会话的事件监听机制,等待会话进入Connected状态后,再执行消息发送操作。修改代码如下:

class TopicPublisher {
    private isConnected = false;
    private connectResolve?: () => void;
    private connectPromise?: Promise<void>;

    private getSession(): Promise<solace.Session> {
        if (this.session && this.isConnected) {
            return Promise.resolve(this.session);
        }

        if (this.connectPromise) {
            return this.connectPromise.then(() => this.session!);
        }

        this.connectPromise = new Promise((resolve, reject) => {
            this.connectResolve = resolve;
            try {
                this.log('Creating session for url=' + this.hosturl+' vpn='+this.vpn+' username='+this.username);
                this.session = this.solace.SolclientFactory.createSession({
                    url: this.hosturl,
                    vpnName: this.vpn,
                    userName: this.username,
                    password: this.pass,
                });

                // 设置会话事件处理器
                this.session.on(solace.SessionEventCode.UP_NOTICE, () => {
                    this.isConnected = true;
                    this.log('Session connected successfully');
                    this.connectResolve?.();
                });

                this.session.on(solace.SessionEventCode.CONNECT_FAILED_ERROR, (error) => {
                    this.log('Connection failed: ' + error.toString());
                    this.session = null;
                    this.isConnected = false;
                    reject(error);
                });

                // 监听断开事件
                this.session.on(solace.SessionEventCode.DISCONNECTED, () => {
                    this.isConnected = false;
                    this.log('Session disconnected');
                });

                try {
                    this.session.connect();
                } catch(error : any) {
                    this.log('Could not initiate connection. Error: '+error.toString());
                    this.session = null;
                    reject(error);
                }

            } catch (error: any) {
                this.log(error.toString());
                reject(error);
            }
        });

        return this.connectPromise.then(() => this.session!);
    }

    public async publish(messageContent: any) {
        try {
            const session = await this.getSession();
            const solaceMessage = this.getSolaceMessage(messageContent);
            this.log('Publishing message "' + messageContent + '" to topic "' + this.topicName + '"...');
            session.send(solaceMessage);
            this.log('Message published.');
        } catch (error: any) {
            this.log(error.toString());
        }
    };
}

2. 关键修改点说明

  • 将getSession改为返回Promise,确保只有在连接成功后才返回可用会话
  • 添加isConnected标记跟踪会话连接状态
  • 通过SessionEventCode.UP_NOTICE事件监听连接成功通知,此时才认为会话可用
  • 通过CONNECT_FAILED_ERROR事件捕获异步连接失败的情况,避免错误持有无效会话
  • publish方法改为异步,等待会话准备完成后再执行发送操作

3. 额外注意事项

  • 即使URL能ping通,Solace的连接流程还包含VPN认证、权限校验等步骤,任何一步未完成都会导致会话处于非可用状态
  • 建议添加会话断开重连的逻辑,确保在网络波动时能自动恢复连接
  • 错误提示WaitingForDNS是会话状态的真实反映,只是此时的状态不一定由DNS解析失败导致,而是连接流程尚未完成

内容的提问来源于stack exchange,提问作者Woodsman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 06:10:39