与服务端通信异步接口的定义方案

1.一般做法是客户端sendMessage,在另外一个线程里不断recv返回的消息,然后通过onMessage虚函数处理返回的消息。

2.这种做法是sendMessage的时候给它设置一个处理应答消息的回调,将所有回调管理起来,当服务端返回应答消息的时候,找到对应的回调执行。

以下做法考虑到LoginViewer是一个界面当应答消息没有返回的时候我们就关闭掉这个界面,此时这个类就销毁了,之后再调用回调会crash掉。

所以这里用的是一个智能指针,虽然解决了上述崩溃的问题,但是又带来一个新的问题,如果应答消息没有返回此时这个对象就销毁不了。可以用一个timer检测应答消息是否超时,如果超时就删除。

// test.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include "Logger.h"
#include <memory>
#include <string>
#include <map>
#include <functional>

struct Message {
	Message(int id, const std::string &content) 
		: id(id), content(content) { }
	int id;
	std::string content;
};

typedef std::shared_ptr<Message> MessagePtr;
typedef std::function<void(const MessagePtr &resPtr)> ResCallback;

class DBus
{
public:
	static DBus* Instance()
	{
		static DBus *instance = NULL;
		if (NULL == instance) {
			instance = new DBus();
		}
		return instance;
	}

	void login(const MessagePtr &request, const ResCallback &resFunc)
	{
		callbacks_[request->id] = resFunc;
		std::cout << "login start" << std::endl;
	}

	void onMessage(const MessagePtr &resPtr)
	{
		ResCallback func = callbacks_[resPtr->id];
		callbacks_.erase(resPtr->id);
		func(resPtr);
	}

private:
	std::map<int, ResCallback> callbacks_;
};

class LoginViewer : public std::enable_shared_from_this<LoginViewer>
{
public:
	LoginViewer()
	{
		test_ = "testtest...";
		std::cout << "LoginViewer" << std::endl;
	}

	~LoginViewer()
	{
		std::cout << "~LoginViewer" << std::endl;
	}

	void login()
	{
		MessagePtr request(new Message(123, "hello, world!"));
		DBus::Instance()->login(request, std::bind(&LoginViewer::loginResult, shared_from_this(), std::placeholders::_1));
	}

private:
	void loginResult(const MessagePtr &resPtr)
	{
		std::cout << test_ << std::endl;
		std::cout << "login result, message id:" << resPtr->id << ", content:" << resPtr->content << std::endl;
	}

private:
	std::string test_;
};

int _tmain(int argc, _TCHAR* argv[])
{
	{	
		std::shared_ptr<LoginViewer> loginViewer(new LoginViewer());
		loginViewer->login();
	}

	MessagePtr response(new Message(123, "success"));
	DBus::Instance()->onMessage(response);

	system("pause");
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值