Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

断线重连机制卡死 #286

Open
SnowMeteors opened this issue Mar 8, 2024 · 1 comment
Open

断线重连机制卡死 #286

SnowMeteors opened this issue Mar 8, 2024 · 1 comment

Comments

@SnowMeteors
Copy link

class CUdpClientListenerImpl : public CUdpClientListener
{
public:

	explicit CUdpClientListenerImpl() :m_Client(this)
	{
	}

	~CUdpClientListenerImpl() override
	{
		this->m_Client->Stop();
	}

	// 连接服务器
	bool Connect()
	{
		// 连接服务器
		if (!this->m_Client->Start(L"127.0.0.1", 4545, false))
			return false;

		// 等待握手建立完毕
		const auto future = std::async(std::launch::async, [this] {
			this->WaitOnHandShake();
		});

		// SSL 握手超时
		if (const auto status = future.wait_for(std::chrono::seconds(10)); status == std::future_status::timeout)
			return false;

		return true;
	}

	// 等待通信组件停止运行
	void Wait() const
	{
		this->m_Client->Wait();
	}

private:

	CUdpArqClientPtr m_Client;

	std::mutex m_Mutex;
	std::condition_variable m_cv;

	// 等待握手建立完毕
	void WaitOnHandShake()
	{
		std::unique_lock lock(this->m_Mutex);
		this->m_cv.wait(lock);
	}

	EnHandleResult OnReceive(IUdpClient* pSender, CONNID dwConnID, const BYTE* pData, const int iLength) override
	{
		dcout << "OnReceive\n";
		return HR_OK;
	}

	EnHandleResult OnClose(IUdpClient* pSender, CONNID dwConnID, EnSocketOperation enOperation, int iErrorCode) override
	{
		dcout << "OnClose\n";
		return HR_OK;
	}

	EnHandleResult OnHandShake(IUdpClient* pSender, CONNID dwConnID) override
	{
		dcout << "OnHandShake\n";
		this->m_cv.notify_all();
		return HR_OK;
	}
};

// 尝试重新连接并发送登录信息
void TryReconnect()
{
	CUdpClientListenerImpl kernel;

	// 尝试重新连接
	if (!kernel.Connect())
	{
		dcout << "尝试断线重连\n";
		return;
	}

	// 等待通信组件停止运行
	kernel.Wait();

	dcout << "服务端断开连接\n";
}

int main()
{
	// 设置控制台输出编码为 UTF-8
#ifdef _DEBUG
	SetConsoleOutputCP(CP_UTF8);
#endif

	// 断线重连
	while (true)
	{
		TryReconnect();
#ifdef _DEBUG
		std::this_thread::sleep_for(std::chrono::seconds(5));
#else
		std::this_thread::sleep_for(std::chrono::seconds(60));
#endif
	}
}

不运行服务器,直接运行上面客户端的代码,会打印 dcout << "OnClose\n";,然后我发现Connect() 会return false,但是
这行 if (!kernel.Connect()) 会一直卡住
我现在要求客户端,第一 正确使用断线重连功能,第二 我的Connect 逻辑 是全部都连接完毕,包括握手等连接完毕,才算成功
我发现if (!this->m_Client->Start(L"127.0.0.1", 4545, false)) 这行竟然成功,都没有开服务器,而且设置了同步连接,为啥还成功呢?求作者解答

@SnowMeteors
Copy link
Author

SnowMeteors commented Mar 8, 2024

或者作者能否出一个简单的Connect 接口函数,作用就是连接成功并且握手成功,并在指定时间内没有超时,返回True 这种之类的?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant