• c++ rpc调用nodejs


    rpc

    远程过程调用,就是调用远程服务器上的方法,返回结果,将需要运行的函数或者进程放到远程服务器上去执行,降低本地服务的能耗。

    安装thrift

    windows下面直接下载可执行文件就行了
    产生cpp文件
    ./thrift-0.16.0.exe --gen cpp camera.idl.txt
    产生nodejs文件
    ./thrift-0.16.0.exe --gen js:node camera.idl.txt
    这样nodejs 的定义和c++的定义声明都自动产生了
    在这里插入图片描述

    nodejs 端

    先要安装thrift
    npm install thrift --save

    使用nodejs编写服务端

    const thrift = require('thrift');
    const cService = require('./gen-nodejs/CameraService.js');
    
    const cameras = {};
    const server = thrift.createServer(cService, {
     addCamera: function (camera, result) {
       cameras[camera.id] = camera
       console.log("camera add:", camera, " current:", camera)
       result(null)
     },
     getCamera: function (id, result) {
       console.log("get:", id)
       result(null, cameras[id])
     }
    });
    
    server.listen(5600);
    console.log('server start at 5600');
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    在这里插入图片描述

    使用c++ 写一个客户端

    #include 
    #include 
    #include 
    #include 
    
    #pragma comment(lib, “libthrift.lib”)
    using namespace ::apache::thrift;
    using namespace ::apache::thrift::protocol;
    using namespace ::apache::thrift::transport;
    using namespace ::apache::thrift::server;
    
    using boost::shared_ptr;
    
    #pragma comment(lib,“libthrift.lib”)//链接库文件
    
    int main(int argc, char** argv) {
    int port = 5600;
    boost::shared_ptr socket(new TSocket(127.0.0.1, port));
    boost::shared_ptr transport(new TBufferedTransport(socket));
    boost::shared_ptr protocol(new TBinaryProtocol(transport));
    Camera came;
    came.id ="1001";
    came.name ="D1 hik";
    came.ssrc ="13200001";
    try {
    	transport->open();
    
    	client.addCamera(came);
        camera came = client.getCamera();
    	transport->close();
    }
    catch (TException& tx) {
    	printf("ERROR:%s\n", tx.what());
    }
    getchar();
    return 0;
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    以上客户端代码为伪代码,读者自行根据生成的代码去做就行,nodejs和c++建立通道后就可以进行通信,如果不需要远程过程调用,只是消息通信,可以使用zeromq

    使用zeromq 和buttonrpc

    zeromq使用订阅发布的方式,比较简单

    建立zeromq的buttonrpc

    buttonrpc建立在zeromq基础之上

    #include "buttonrpc.hpp"
    #include 
    struct camera
    {
    string camera;
    string name;
    uint32_t ssrc;
    }
     unordered_map<uint32_t, camera*> g_maps;
    string camera_find(uint32_t  cameraid){
    	return g_maps[cameraid];
    }
     
    int main()
    {
    	buttonrpc server;
    	server.as_server(6000);
     
    	server.bind("camera_find", camera_find);
    	server.run();
     
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    #include 
    #include "buttonrpc.hpp"
     
    int main()
    {
    	buttonrpc client;
    	client.as_client("127.0.0.1", 6000);
    	camera a = client.call<int>("camera_find", 2, 3);
    	std::cout << "camera id result: " << a.id << std::endl;
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    nodejs和buttonrpc

    必须使用二进制方式进行通信,可以抓包分析,nodejs端需要写一些代码,因为没有像thrift一样自动生成

    nodejs 单独启动rpc进程

    在nodejs里面使用单独一个进程启动rpc服务

    let cp = require('child_process');
    let worker = cp.fork('./rpc_thrift.js');
     
     
    // 用于监听子进程传来的信息
    worker.on('message', ( data ) =>{
        console.log('receive the data: ', data);
        if(data ==  "exit")
           ...
    })
    //向子进程发送信息
    worker.send('this is server ');
    
    setTimeout(()=>{
        process.send({name: '1111111'});
    },1000)
    
    // 监听父进程的消息
    process.on('message', (data) => {
        console.log('recv', data);
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
  • 相关阅读:
    webpack 中,filename 和 chunkFilename 的区别
    angular 实现模块共享
    【Nowcoder-TOP101】BM1.小明打联盟
    使用消息队列解决RTOS多线程同时打印串口乱序问题
    计算机网络原理 谢希仁(第8版)第四章习题答案
    JVM基本常识了解
    Tomcat报BAD packet signature 18245错误的原因
    浏览器从输入URL到页面出来的过程
    2021 Java 这一年
    矢量叉乘能否反求矢量
  • 原文地址:https://blog.csdn.net/qianbo042311/article/details/126801874