使用WebSocket在java/spring和c++/qt应用程序之间进行通信 我尝试使用Spring用java/Web应用程序实现WebSoCube,允许它用C++和Qt和WebSoCub库编写的应用程序交换消息。

使用WebSocket在java/spring和c++/qt应用程序之间进行通信 我尝试使用Spring用java/Web应用程序实现WebSoCube,允许它用C++和Qt和WebSoCub库编写的应用程序交换消息。,java,c++,spring,qt,websocket,Java,C++,Spring,Qt,Websocket,我的java/spring应用程序中有以下配置: WebScoketConfig.java SocketHandler.java 但是,当我执行这两个应用程序,并尝试为java/web应用程序发送消息时,什么都没有发生。我很确定我犯的错误是在c++/qt端,因为在java/spring端,我有一个html/javascript代码,允许我测试消息exchage,nd工作正常 谁能告诉我我做错了什么 更新:最小可复制示例-java/spring 项目可以使用start.spring.io生成,但只

我的java/spring应用程序中有以下配置:

WebScoketConfig.java

SocketHandler.java

但是,当我执行这两个应用程序,并尝试为java/web应用程序发送消息时,什么都没有发生。我很确定我犯的错误是在c++/qt端,因为在java/spring端,我有一个html/javascript代码,允许我测试消息exchage,nd工作正常

谁能告诉我我做错了什么

更新:最小可复制示例-java/spring

项目可以使用start.spring.io生成,但只能使用SpringWebSocket作为依赖项。除了上面我已经添加的2个文件外,该项目还将包括:

参考资料/static/index.html

使用mvn包构建之后,只需使用java-jar target/app.jar运行即可

更新:最小可复制示例-c++/qt

项目是使用qt创建者创建的,类型为qt小部件。它将创建一个包含5个文件的项目:websocket.pro、mainwindow.ui、mainwindow.h、mainwindow.cpp和main.cpp

打开mainwindow.ui并从工具栏添加lineEdit和按钮。右键单击按钮并选择“转到插槽”,然后选择“单击”。添加上面的代码

更新2


问题是,您试图发送文本时没有验证连接是否成功。解决方案是使用已连接的信号,并按照注释中的建议使m_webSocket成为类的成员:

*h

私人: Ui::MainWindow*Ui; QWebSocket m_webSocket; *.cpp

void main window::单击按钮时 { QString message=ui->lineEdit->text; connect&m_webSocket,&QWebSocket::connected,[此,消息]{ m_webSocket.sendTextMessageHello+message+!; m_webSocket.close; }; m_webSocket.openQUrlQStringLiteralws://localhost:8080/name; } 更新: 在您的项目中,我注意到以下错误:

由于某种原因,当我使用Google Chrome进行测试时,我无法连接,所以我添加了registry.addHandlernew-SocketHandler,/name.setAllowedOrigins*;对配置进行修改

变量会话只处理向套接字发送数据,如果要将该信息发送到所有套接字js和qt,则必须迭代

断开会话连接时,不要将其从会话中删除,否则会导致错误。必须在afterConnectionClosed方法中删除会话

在您的代码中,您正在调用与已连接信号关联的插槽中连接到服务器,这是愚蠢的,因为该插槽是在连接之后调用的,为此,您应该首先调用open方法。无论如何,打开连接、等待连接建立、发送消息并关闭连接都不是一个好主意,最好在发送消息之前打开连接,并在必要时关闭连接,例如在关闭GUI时,或者用户希望像在js中那样关闭连接,因为信息的发送不是即时的,而是异步的


完整的代码是。

不确定,但。。。我猜QWebSocket::sendTextMessage实际上不会立即发送消息。相反,它将延迟发送,直到您将控制返回到Qt事件循环。在这种情况下,当您的QWebSocket超出范围时,消息可能会丢失。我如何解决此问题?如果没有,很难回答,但是,请尝试使QWebSocket m_webSocket成为类MainWindow的数据成员。不知道是否会有帮助,我尝试更新我的问题,以包含此最小的可复制示例,因为仅仅让m_websocket成为MainWindow的数据成员并不能使它起作用。@KleberMota你说什么都没有发生,这是什么意思?您希望得到什么?嗯,有趣的是,当我复制/粘贴您的代码时,c++/qt应用程序似乎到达了java/spring应用程序,但我得到了以下错误:com.google.gson.JsonSyntaxException:java.lang.IllegalStateException:应该是BEGIN_对象,但在第1行第1列路径$处是字符串。如果我将代码更改为添加到问题中的“查看更新2”,则不会显示任何错误,但似乎没有向java/spring应用程序发送任何内容。@KleberMota对我来说太奇怪了。也许我们的项目有一些不同,你能把两个应用程序都上传到GITHUB,除了指出你使用的所有库的版本吗?2个项目是:java,C++ +kelBoMeta。我已经更正了你的代码,并为你的RePOS创建了2个PRS。
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(new SocketHandler(), "/name");
    }
}
@Component
public class SocketHandler extends TextWebSocketHandler {
    List<WebSocketSession> sessions = new CopyOnWriteArrayList<>();

    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message) throws InterruptedException, IOException {
        Map<String, String> value = new Gson().fromJson(message.getPayload(), Map.class);
        session.sendMessage(new TextMessage("Hello " + value.get("name") + " !"));
    }

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        sessions.add(session);
    }
}
void MainWindow::on_pushButton_clicked()
{
    QString message = this->ui->lineEdit->text();
    QWebSocket m_webSocket;
    m_webSocket.open(QUrl(QStringLiteral("ws://localhost:8080/name")));
    m_webSocket.sendTextMessage("Hello " + message + " !");
    m_webSocket.close();
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Hello WebSocket</title>
  <link href="/main.css" rel="stylesheet">
</head>
<body>
  <table>
    <tr>
      <td>
        <button id="connect" type="button" onclick="connect();">Connect</button>
        <button id="disconnect" type="button" disabled="disabled" onclick="disconnect();">Disconnect</button>
      </td>
      <td>
        <label for="name">What is your name?</label>
        <input type="text" id="name" placeholder="Your name here...">
        <button id="send" type="button" onclick="send();">Send</button>
      </td>
    </tr>
  </table>

  <hr>

  <table id="conversation" border="2">
      <thead>
      <tr>
          <th>Greetings</th>
      </tr>
      </thead>
      <tbody id="greetings">
      </tbody>
  </table>

  <script src="/app.js"></script>
</body>
</html>
function connect() {
    ws = new WebSocket('ws://localhost:8080/name');

    ws.onmessage = function(text) {
    var tr = document.createElement("tr");
    var td = document.createElement("td");
    td.innerText = text.data;
    tr.appendChild(td);
    document.querySelector("#greetings").appendChild(tr);
    }

  document.querySelector("#connect").setAttribute("disabled", "disabled");
  document.querySelector("#disconnect").removeAttribute("disabled");
  document.querySelector("#conversation").style.display = 'block';
  document.querySelector("#greetings").innerHTML = "";
}

function disconnect() {
    if (ws != null)
        ws.close();

    document.querySelector("#connect").removeAttribute("disabled");
    document.querySelector("#disconnect").setAttribute("disabled", "disabled");
    document.querySelector("#conversation").style.display = 'none';
    document.querySelector("#greetings").innerHTML = "";
}

function send() {
  var name = document.querySelector("#name");
    var data = JSON.stringify({'name': name.value});
  ws.send(data);
}
void MainWindow::on_pushButton_clicked()
{
    QString message = ui->lineEdit->text();

    connect(&m_webSocket, &QWebSocket::connected, [this, message](){
        QJsonObject object
        {
            {"name", message}
        };
        QJsonDocument d(object);
        m_webSocket.sendTextMessage(d.toJson().toStdString().c_str());
        m_webSocket.close();
    });

    m_webSocket.open(QUrl(QStringLiteral("ws://localhost:8080/name")));
}