繁体   English   中英

Node.js和C ++之间的集成

[英]Integration between Node.js and C++

我有一个Node.js应用程序,我希望能够将JSON对象发送到C ++应用程序中。

C ++应用程序将使用Poco库(pocoproject.org)。

我希望交互能够快速启动,因此最好不要包含文件或网络套接字。 我一直在研究以下领域:

  • 管道
  • 共享内存
  • unixSockets

我应该重点关注什么,有人可以将我的方向指向文档。 和样品?

首先,需要更多数据才能提供良好建议。

通常,共享内存是最快的,因为不需要传输,但也很难保持良好。 我不确定您是否可以使用Node做到这一点。

如果此程序仅针对该任务运行并关闭,则仅将JSON作为启动参数发送给CPP程序可能值得

myCPPProgram.exe "JsonDataHere"

性能最简单的事情应该是使用带有某些低开销数据帧格式的Unix域套接字的套接字连接。 例如,两个字节的长度,后跟UTF-8编码的JSON。 在C ++方面,使用Poco::Net::TCPServer框架应该很容易实现。 取决于您的应用程序将来的去向,您可能会遇到这种格式的限制,但是如果基本上只是流JSON对象,那应该没问题。

为了使其更简单,您可以使用WebSocket,它会为您处理帧,但以初始连接设置(HTTP升级请求)的开销为代价。 甚至有可能在Unix域套接字上运行WebSocket协议。

但是,考虑到所有JavaScript / node.js的开销,(仅本地主机)TCP套接字和Unix域套接字之间的性能差异甚至可能并不明显。 另外,如果确实要考虑性能,那么JSON甚至可能不是正确的序列化格式。

无论如何,没有更详细的信息(JSON数据的大小,消息频率),很难给出明确的建议。

我创建了一个TCPServer,它似乎可以正常工作。 但是,如果我关闭服务器并重新启动,则会出现此错误:

网络异常:地址已在使用中:/tmp/app.SocketTest

如果存在,是否无法重新连接到插座?

这是TCPServer的代码:

#include "Poco/Util/ServerApplication.h"
#include "Poco/Net/TCPServer.h"
#include "Poco/Net/TCPServerConnection.h"
#include "Poco/Net/TCPServerConnectionFactory.h"
#include "Poco/Util/Option.h"
#include "Poco/Util/OptionSet.h"
#include "Poco/Util/HelpFormatter.h"
#include "Poco/Net/StreamSocket.h"
#include "Poco/Net/ServerSocket.h"
#include "Poco/Net/SocketAddress.h"
#include "Poco/File.h"
#include <fstream>
#include <iostream>

using Poco::Net::ServerSocket;
using Poco::Net::StreamSocket;
using Poco::Net::TCPServer;
using Poco::Net::TCPServerConnection;
using Poco::Net::TCPServerConnectionFactory;
using Poco::Net::SocketAddress;
using Poco::Util::ServerApplication;
using Poco::Util::Option;
using Poco::Util::OptionSet;
using Poco::Util::HelpFormatter;



class UnixSocketServerConnection: public TCPServerConnection
    /// This class handles all client connections.
{
public:
    UnixSocketServerConnection(const StreamSocket& s): 
        TCPServerConnection(s)
    {
    }

    void run()
    {
        try
        {
            /*char buffer[1024];
            int n = 1;
            while (n > 0)
            {
                n = socket().receiveBytes(buffer, sizeof(buffer));
                EchoBack(buffer);
            }*/

            std::string message;
            char buffer[1024];
            int n = 1;
            while (n > 0)
            {
                n = socket().receiveBytes(buffer, sizeof(buffer));
                buffer[n] = '\0';
                message += buffer;
                if(sizeof(buffer) > n && message != "")
                {
                    EchoBack(message);
                    message = "";
                }
            }
        }
        catch (Poco::Exception& exc)
        {
            std::cerr << "Error: " << exc.displayText() << std::endl;
        }
        std::cout << "Disconnected." << std::endl;
    }

private:
    inline void EchoBack(std::string message)
    {
        std::cout << "Message: " << message << std::endl;
        socket().sendBytes(message.data(), message.length());
    }
};

class UnixSocketServerConnectionFactory: public TCPServerConnectionFactory
    /// A factory
{
public:
    UnixSocketServerConnectionFactory()
    {
    }

    TCPServerConnection* createConnection(const StreamSocket& socket)
    {
        std::cout << "Got new connection." << std::endl;
        return new UnixSocketServerConnection(socket);
    }

private:

};

class UnixSocketServer: public Poco::Util::ServerApplication
    /// The main application class.
{
public:
    UnixSocketServer(): _helpRequested(false)
    {
    }

    ~UnixSocketServer()
    {
    }

protected:
    void initialize(Application& self)
    {
        loadConfiguration(); // load default configuration files, if present
        ServerApplication::initialize(self);
    }

    void uninitialize()
    {
        ServerApplication::uninitialize();
    }

    void defineOptions(OptionSet& options)
    {
        ServerApplication::defineOptions(options);

        options.addOption(
            Option("help", "h", "display help information on command line arguments")
                .required(false)
                .repeatable(false));
    }

    void handleOption(const std::string& name, const std::string& value)
    {
        ServerApplication::handleOption(name, value);

        if (name == "help")
            _helpRequested = true;
    }

    void displayHelp()
    {
        HelpFormatter helpFormatter(options());
        helpFormatter.setCommand(commandName());
        helpFormatter.setUsage("OPTIONS");
        helpFormatter.setHeader("A server application to test unix domain sockets.");
        helpFormatter.format(std::cout);
    }

    int main(const std::vector<std::string>& args)
    {
        if (_helpRequested)
        {
            displayHelp();
        }
        else
        {
            // set-up unix domain socket
            Poco::File socketFile("/tmp/app.SocketTest");
            SocketAddress unixSocket(SocketAddress::UNIX_LOCAL, socketFile.path());

            // set-up a server socket
            ServerSocket svs(unixSocket);
            // set-up a TCPServer instance
            TCPServer srv(new UnixSocketServerConnectionFactory, svs);
            // start the TCPServer
            srv.start();
            // wait for CTRL-C or kill
            waitForTerminationRequest();
            // Stop the TCPServer
            srv.stop();
        }
        return Application::EXIT_OK;
    }

private:
    bool _helpRequested;
};

int main(int argc, char **argv) {
    UnixSocketServer app;
    return app.run(argc, argv);
}

我寻求的解决方案是使用Unix域套接字。 该解决方案将在Raspbian安装程序上运行,并且套接字文件位于/ dev / shm中,该文件已安装到RAM中。

在C ++方面,我使用Poco :: Net :: TCPServer框架,如本文其他地方所述。

在Node.js端,我使用node-ipc模块( http://riaevangelist.github.io/node-ipc/ )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM