Едновременни извиквания на отдалечени процедури към C++ обект

Бих искал да имам клас, написан на C++, който да действа като отдалечен сървър за извикване на процедури.

Имам голям (над гигабайт) файл, който анализирам, четейки параметри, за да инстанцирам обекти, които след това съхранявам в std::map. Бих искал RPC сървърът да слуша за повиквания от клиент, да взема параметрите, предадени от клиента, да търси подходяща стойност в картата, да прави изчисление и да връща изчислената стойност обратно на клиента и искам да обслужват едновременни заявки -- така че бих искал да имам няколко слушащи нишки. Между другото, след като картата се попълни, тя не се променя. Заявките ще се четат само от него.

Бих искал да напиша клиента на Python. Може ли сървърът да бъде просто HTTP сървър, който слуша POST заявки и клиентът може да използва urllib, за да ги изпрати?

Нов съм в C++, така че нямам представа как да напиша сървъра. Може ли някой да ме насочи към някои примери?


person John Thompson    schedule 17.07.2013    source източник
comment
Защо C++? Можете просто да напишете Python сървър (stackoverflow.com/questions /14088294/). Ако изчислението ви отнема време или в C++, просто го обвийте с помощта на ctypes   -  person user1827356    schedule 18.07.2013
comment
Не можете да правите нишки в Python, само многопроцесорни -- така че не мога да имам нещото с резбованата карта, което искам да имам, ако сървърът е в Python.   -  person John Thompson    schedule 18.07.2013
comment
@JohnPeterThompsonGarcés: Първо, да, вие можете да правите нишки в Python. Ако имате нужда само от едновременни заявки, сте готови. Ако имате нужда от едновременни заявки, обвързани с процесора, където кодът, обвързан с процесора, е вашият C++ клас, просто накарайте вашата обвивка да освободи GIL около извикванията в този клас. И докато сме там, не е толкова трудно да споделяте std::map между процесите.   -  person abarnert    schedule 18.07.2013
comment
Няма ли никакво споделяне между процеси да изисква много предаване на съобщения? Искам да използвам споделена памет. Говорите за освобождаване на GIL. Това звучи сложно.   -  person John Thompson    schedule 18.07.2013
comment
Можете да споделяте картата в нишки, точно както бихте направили в C++. За GIL намирам това за полезно (docs.python.org/ release/1.5.2/api/threads.html) По-специално - Py_BEGIN_ALLOW_THREADS ...Извършете блокираща I/O операция... Py_END_ALLOW_THREADS   -  person user1827356    schedule 18.07.2013


Отговори (2)


Може би фактори могат да повлияят на избора.

Едно решение е да използвате fastcgi.

Клиентът изпраща HTTP заявка до HTTP сървър, който има активиран fastCGI. HTP сървърът изпраща заявката до вашия RPC сървър чрез механизма fastcgi. RPC сървърът обработва и генерира отговор и го изпраща обратно към http сървъра. http сървърът изпраща отговора обратно на вашия клиент.

person ROTOGG    schedule 17.07.2013

Ако трябва да напишете сървъра на C++ и нямате представа как да го направите, определено искате да използвате рамка.

Има много възможности за избор и StackOverflow не е добро място да питате за мнения относно различни възможности за избор. Но за да ви дам един пример, JsonRpc-Cpp ви позволява да внедрите JSON -RPC (през необработен TCP или HTTP) сървър в около 10 реда код, плюс ред шаблон за всеки RPC, който искате да изложите. Много по-лесно от писането на сървър от нулата.

И така, ето един примерен сървър:

#include <cstdlib>
#include <jsonrpc.h>

class Service {
public:
    bool echo(const Json::Value &root, Json::Value &response) {
        response["jsonrpc"] = "2.0";
        response["id"] = root["id"];
        Json::Value result;
        result["params"] = root["params"];
        response["result"] = result;
        return response;
    }
}

int main(int argc, char *argv[]) {
    int port = std::atoi(argv[1]); // add some error handling here...

    Json::Rpc::TcpServer server("127.0.0.1", port);
    Service service;
    server.AddMethod(new Json::Rpc::RpcMethod<Service>(service,
                     &Service::echo, "echo");
    server.Bind(); // add error handling again
    server.Listen();
    while(true) server.WaitMessage(1000);
}

Вероятно обаче ще бъде още по-лесно, ако напишете сървъра на Python или използвате WSGI уеб сървър и напишете услуга на Python и извикате C++ кода от Python (независимо дали чрез ctypes или чрез изграждане на обвивка с нещо като Cython или SIP).

Ето същия сървър в Python, използващ bjsonrpc:

import bjsonrpc

class Service(bjsonrpc.handlers.BaseHandler):
    def echo(self, *args):
        return {'params': args}

server = bjsonrpc.createserver(handler_factory = Service)
server.serve()
person abarnert    schedule 17.07.2013