qicosmos / rest_rpc

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

client connect()会神秘的返回true (server端就根本没启动) #16

Closed wzhou1974 closed 3 years ago

wzhou1974 commented 3 years ago

libtest.cpp如下

include "thread"

include "iostream"

include "chrono"

include "rpc_client.hpp"

using namespace rest_rpc; using namespace rest_rpc::rpc_service;

bool online {};

bool init() { std::thread check_thread([] () { rpc_client check_client("127.0.0.1", 3000);

    while (true) {
        auto current_status = check_client.connect();
        check_client.close();
        std::cout << "check server ..." << std::endl;

        if (current_status == online) {
            // do nothing
        } else {
            online = current_status;
            if (!current_status) {
                std::cout << "server is offline" << std::endl;
            } else {
                std::cout << "server is online ..." << std::endl;
            }               
        }

        std::this_thread::sleep_for(std::chrono::seconds(5));
    }
});
check_thread.detach();

return true;

}

build libtest.cpp to shared library (.so file)

g++ -fPIC -shared -o libtest.so libtest.cpp -I./rest_rpc/include -I./rest_rpc/third/msgpack/include -Ipthread

test-1.cpp如下

include "thread"

include "iostream"

bool init();

int main() { init();

while (true) {
    std::this_thread::sleep_for(std::chrono::seconds(5));
}

// ...  
std::cout << __LINE__ << std::endl;

return 0;

}

链接libtest.so生成可执行文件

g++ -o test-1 test-1.cpp -std=c++11 -I./rest_rpc/include -I./rest_rpc/third/msgpack/include -lpthread -ltest -L.

下面是运行test-1的片段

$ ./test-1 check server ... check server ... check server ... check server ... server is online ... check server ... server is offline check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... server is online ... check server ... server is offline check server ... check server ... check server ... server is online ... check server ... server is offline check server ... check server ... check server ... server is online ... check server ... server is offline check server ... check server ... check server ... server is online ... check server ... server is offline check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... server is online ... check server ... server is offline check server ...

这里server (port 3000)就根本没有启动,但test-1在运行时会时不时的变现connect()会返回true,而且概率还蛮高的。

wzhou1974 commented 3 years ago

如果是正常的输出,应该只看到check server...的输出。因为connect()总是返回false。

wzhou1974 commented 3 years ago

另外,我comment out check_client.close()那一行,表现也是一样,也会出现间歇性的connect()返回true

    while (true) {
        auto current_status = check_client.connect();

// check_client.close(); std::cout << "check server ..." << std::endl;

        if (current_status == online) {
            // do nothing
        } else {
            online = current_status;
            if (!current_status) {
                std::cout << "server is offline" << std::endl;
            } else {
                std::cout << "server is online ..." << std::endl;
            }               
        }

comment out check_client.close()后的输出

$ ./test-1 check server ... check server ... check server ... check server ... server is online ... check server ... server is offline check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... server is online ... check server ... server is offline

qicosmos commented 3 years ago

已经修复了这个问题。

原因:一个重连次数的判断条件不对,导致client connect失败之后会自动异步重连,外面也会去连接,这里造成了多线程调用了异步连接,导致返回的状态不对。

qicosmos commented 3 years ago

libtest.cpp如下

include "thread"

include "iostream"

include "chrono"

include "rpc_client.hpp"

using namespace rest_rpc; using namespace rest_rpc::rpc_service;

bool online {};

bool init() { std::thread check_thread([] () { rpc_client check_client("127.0.0.1", 3000);

  while (true) {
      auto current_status = check_client.connect();
      check_client.close();
      std::cout << "check server ..." << std::endl;

      if (current_status == online) {
          // do nothing
      } else {
          online = current_status;
          if (!current_status) {
              std::cout << "server is offline" << std::endl;
          } else {
              std::cout << "server is online ..." << std::endl;
          }               
      }

      std::this_thread::sleep_for(std::chrono::seconds(5));
  }
});
check_thread.detach();

return true;

}

build libtest.cpp to shared library (.so file)

g++ -fPIC -shared -o libtest.so libtest.cpp -I./rest_rpc/include -I./rest_rpc/third/msgpack/include -Ipthread

test-1.cpp如下

include "thread"

include "iostream"

bool init();

int main() { init();

while (true) {
  std::this_thread::sleep_for(std::chrono::seconds(5));
}

// ...    
std::cout << __LINE__ << std::endl;

return 0;

}

链接libtest.so生成可执行文件

g++ -o test-1 test-1.cpp -std=c++11 -I./rest_rpc/include -I./rest_rpc/third/msgpack/include -lpthread -ltest -L.

下面是运行test-1的片段

$ ./test-1 check server ... check server ... check server ... check server ... server is online ... check server ... server is offline check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... server is online ... check server ... server is offline check server ... check server ... check server ... server is online ... check server ... server is offline check server ... check server ... check server ... server is online ... check server ... server is offline check server ... check server ... check server ... server is online ... check server ... server is offline check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... check server ... server is online ... check server ... server is offline check server ...

这里server (port 3000)就根本没有启动,但test-1在运行时会时不时的变现connect()会返回true,而且概率还蛮高的。

另外这个地方:std::this_thread::sleep_for(std::chrono::seconds(5)); 是不必要的,因为connect默认就是3秒超时,如果你希望超时时间更长,改成connect(8s)即可。

wzhou1974 commented 3 years ago

I have retested the issue, the bug has been fixed. Thanks.