qicosmos / rest_rpc

modern C++(C++11), simple, easy to use rpc framework
MIT License
1.7k stars 370 forks source link

简单的rest_rpc出错 #88

Open summerlotus513 opened 1 year ago

summerlotus513 commented 1 year ago

最简单的rest_rpc demo server

#include <stdio.h>
#include <iostream>
#include <fstream>
#include <string>

#include <rest_rpc.hpp>

using namespace rest_rpc;
using namespace rpc_service;

void hello(rpc_conn conn, const std::string &str) {
  std::cout << "hello " << str << std::endl;
}

int main(int argc, char *argv[]) {

    rpc_server server(9000, std::thread::hardware_concurrency());

    server.register_handler("hello", hello);
    server.set_network_err_callback(
        [](std::shared_ptr<connection> conn, std::string reason) {
            std::cout << "remote client address: " << conn->remote_address()
                    << " networking error, reason: " << reason << "\n";
        });

    server.run();

    return 0;
}

client

#include <chrono>
#include <fstream>
#include <iostream>
#include <rest_rpc.hpp>

using namespace rest_rpc;
using namespace rest_rpc::rpc_service;

void test_hello() {
    try {
        rpc_client client("127.0.0.1", 9000);
        bool r = client.connect();
        if (!r) {
            std::cout << "connect timeout" << std::endl;
            return;
        }
        client.call<2000, std::string>("hello", "rest_rpc");
    } catch (const std::exception &e) {
        std::cout << "Err." << e.what() << std::endl;
    }
}

void test_connect() {
    rpc_client client;
    client.enable_auto_reconnect(); // automatic reconnect
    client.enable_auto_heartbeat(); // automatic heartbeat
    bool r = client.connect("127.0.0.1", 9000);
    int count = 0;
    while (true) {
        if (client.has_connected()) {
            std::cout << "connected ok\n";
            break;
        }
        else {
            std::cout << "connected failed: " << count++ << "\n";
        }
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
}

int main(int argc, char *argv[]) {
    test_connect();
    test_hello();

    return 0;
}

报错信息如下: server

remote client address: 127.0.0.1 networking error, reason: End of file
remote client address: 127.0.0.1 networking error, reason: End of file
remote client address: 127.0.0.1 networking error, reason: End of file
remote client address: 127.0.0.1 networking error, reason: End of file
remote client address: 127.0.0.1 networking error, reason: End of file
remote client address: 127.0.0.1 networking error, reason: End of file
remote client address: 127.0.0.1 networking error, reason: End of file
remote client address: 127.0.0.1 networking error, reason: End of file
remote client address: 127.0.0.1 networking error, reason: End of file
hello rest_rpc
remote client address: 127.0.0.1 networking error, reason: End of file
remote client address: 127.0.0.1 networking error, reason: End of file
hello rest_rpc
remote client address: 127.0.0.1 networking error, reason: End of file
remote client address: 127.0.0.1 networking error, reason: End of file

client

user@server:~/application/rest_rpc_master/demo/build$ ./basic_client 
connected ok
End of file
Segmentation fault
user@server:~/application/rest_rpc_master/demo/build$ ./basic_client 
connected ok
End of file
Segmentation fault
user@server:~/application/rest_rpc_master/demo/build$ ./basic_client 
connected ok
End of file
Segmentation fault
user@server:~/application/rest_rpc_master/demo/build$ ./basic_client 
connected ok
Operation aborted.
basic_client: tpp.c:84: __pthread_tpp_change_priority: Assertion `new_prio == -1 || (new_prio >= fifo_min_prio && new_prio <= fifo_max_prio)' failed.
Aborted
user@server:~/application/rest_rpc_master/demo/build$ ./basic_client 
connected ok
Operation aborted.
basic_client: ../nptl/pthread_mutex_lock.c:433: __pthread_mutex_lock_full: Assertion `INTERNAL_SYSCALL_ERRNO (e, __err) != ESRCH || !robust' failed.
Aborted
user@server:~/application/rest_rpc_master/demo/build$ ./basic_client 
connected ok
Operation aborted.
Operation aborted.
user@server:~/application/rest_rpc_master/demo/build$ ./basic_client 
connected ok
End of file
Operation aborted.
user@server:~/application/rest_rpc_master/demo/build$

当我吧asio更新至最新后,段错误便不会出现了,但是依然有Operation aborted的错误

summerlotus513 commented 1 year ago

我怀疑是socket的close导致的问题: https://stackoverflow.com/questions/7732726/bad-file-descriptor-closing-boost-socket 按照上述的说法,似乎不应该手动调用socket的close方法? 而且,在每次调用完成后,使用netstat -nat | grep 9000查看,发现连接仍然存在,未被关闭。

qicosmos commented 1 year ago

用的最新代码测试的吗? linux还是windowx下测试的? 我用这个代码在mac下测了一下。

server输出:

remote client address: 127.0.0.1 networking error, reason: End of file
hello rest_rpc
remote client address: 127.0.0.1 networking error, reason: End of file

client 输出:

connected ok
End of file

这个输出是正常的。 client请求完之后会关闭连接,所以会打印出eof; client断开之后server也会关闭对应的client的socket,同样会打印eof。

oldn123 commented 8 months ago

我这里在linux上客户端在远程调用后也是遇到这个提示: Operation aborted.

用的最新的代码,启用这个宏:MSGPACK_NO_BOOST;

代码比较简单:

try {
    rpc_client client("127.0.0.1", 9000);
    bool r = client.connect(3);
    if (!r) {
        return -1;
    }

    auto result = client.call<std::string>("forward-args", sArgStr);
    std::cout << "forward-args ret:" << result << std::endl;
}
catch (const std::exception& e) {
    return -1;
}
catch (const std::out_of_range& e) {
    return -1;
}
catch (...) {
    return -1;
}