diff --git a/sources/scripting/liveserver.cpp b/sources/scripting/liveserver.cpp index 76e292bd5..5aa9aa01c 100644 --- a/sources/scripting/liveserver.cpp +++ b/sources/scripting/liveserver.cpp @@ -280,6 +280,15 @@ void LiveServer::handle(const QJsonObject &request) if (request.contains(QStringLiteral("id"))) answer.insert(QStringLiteral("id"), request.value(QStringLiteral("id"))); send(answer); + //One request per connection: close it from this side once it is + //answered. Waiting for the client to hang up raced the next + //request on Windows, where a named pipe's disconnection reaches + //QLocalSocket late -- the second call of a quick pair was turned + //away as "another assistant" (found under Wine, 2026-10-02). + if (m_client) { + m_client->disconnectFromServer(); + m_client = nullptr; + } emit handled(request, answer); } diff --git a/sources/scripting/liveserver.h b/sources/scripting/liveserver.h index dfc92dce9..1f8b9135a 100644 --- a/sources/scripting/liveserver.h +++ b/sources/scripting/liveserver.h @@ -40,8 +40,8 @@ class QWidget; The channel is a QLocalServer only the user's own account can open, with a random name and token written to live-session.json in the data folder, which the MCP server reads; the file goes when the channel - closes. One request per line, one answer per line, both JSON; every - request carries the token. + closes. One JSON request per connection, one JSON answer back, then + the server closes the connection; every request carries the token. Requests are never handled inside the socket's readyRead: each is queued to the event loop first. QETApp::receiveMessage() learnt why --