您的位置:首页 > 其它

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

2014-10-30 19:27 302 查看
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: