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;
}