Я много экспериментировал и создал минимальный рабочий пример.В этом примере я отправляю запрос инициализации в ccls (который является языковым сервером C ++) и зачитываю ответ.Я использовал QProcess для запуска сервера (но, конечно, можно использовать что-то другое) и rapidjson (https://github.com/Tencent/rapidjson) для построения файла json.
#include <QCoreApplication>
#include <QProcess>
#include <iostream>
#include <sstream>
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"
int main(int argc, char* argv[]) {
QCoreApplication app {argc, argv};
//Start server as a QProcess
QProcess* server = new QProcess {&app};
server->start("ccls", QStringList {"-log-file=/tmp/ccls2.log", "-init={}"});
server->waitForStarted(-1);
std::cout << "Server started" << '\n';
//Construct json Request
rapidjson::StringBuffer output {};
rapidjson::Writer<rapidjson::StringBuffer> writer {output};
writer.StartObject();
writer.Key("jsonrpc");
writer.String("2.0");
writer.Key("id");
writer.Int(0);
writer.Key("method");
writer.String("initialize");
writer.Key("params");
writer.StartObject();
writer.Key("processId");
writer.Int(0);
writer.Key("rootUri");
writer.String("home");
writer.Key("capabilities");
writer.StartObject();
writer.EndObject();
writer.EndObject();
writer.EndObject();
std::string content = output.GetString();
std::ostringstream oss;
oss << "Content-Length: " << content.length() << "\r\n" << "\r\n";
std::string header = oss.str();
std::cout << header << content << '\n';
//Send request to server
server->write(header.c_str());
server->write(content.c_str());
//Wait for response and read it
server->waitForReadyRead(-1);
std::cout << "Server has sent response" << '\n';
std::cout << server->readAll().toStdString() << '\n';
return app.exec();
}
И вывод:
Server started
Content-Length: 106
{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":0,"rootUri":"home","capabilities":{}}}
Server has sent response
Content-Length: 1046
{"jsonrpc":"2.0","id":0,"result":{"capabilities":{"textDocumentSync":{"openClose":true,"change":2,"willSave":false,"willSaveWaitUntil":false,"
save":{"includeText":false}},"hoverProvider":true,"completionProvider":{"resolveProvider":false,"triggerCharacters":[".",":",">","#","<","\"",
"/"]},"signatureHelpProvider":{"triggerCharacters":["(",","]},"definitionProvider":true,"implementationProvider":true,"typeDefinitionProvider"
:true,"referencesProvider":true,"documentHighlightProvider":true,"documentSymbolProvider":true,"workspaceSymbolProvider":true,"codeActionProvi
der":{"codeActionKinds":["quickfix"]},"codeLensProvider":{"resolveProvider":false},"documentFormattingProvider":true,"documentRangeFormattingP
rovider":true,"documentOnTypeFormattingProvider":{"firstTriggerCharacter":"}","moreTriggerCharacter":[]},"renameProvider":true,"documentLinkPr
ovider":{"resolveProvider":true},"foldingRangeProvider":true,"executeCommandProvider":{"commands":["ccls.xref"]},"workspace":{"workspaceFolder
s":{"supported":true,"changeNotifications":true}}}}}
Как я уже сказал, я хотел показать всем, у кого один и тот же вопрос, минимальный рабочий пример. Конечно, имеет смысл создавать структуры для Request и т. Д.