Index: /trunk/msg.hpp
===================================================================
--- /trunk/msg.hpp	(revision 11)
+++ /trunk/msg.hpp	(revision 12)
@@ -56,8 +56,8 @@
 		Message();
 
-		inline void parse(const std::string & message);
+		void parse(const std::string & message);
 
 		template<typename T>
-		inline T get(const std::string & key) const
+		T get(const std::string & key) const
 		{
 			return (T)mObject[key];
@@ -65,5 +65,5 @@
 
 		template<typename T>
-		inline std::vector<T> getList(const std::string & key) const
+		std::vector<T> getList(const std::string & key) const
 		{
 			std::vector<T> ret;
@@ -76,7 +76,7 @@
 		}
 
-		inline std::vector<SFriend> getFriendList() const;
+		std::vector<SFriend> getFriendList() const;
 
-		inline std::string type() const;
+		std::string type() const;
 	};
 
@@ -93,23 +93,23 @@
 
 	public:
-		inline void setUserID(const std::string & id);
+		void setUserID(const std::string & id);
 
-		inline const std::string & getUserID();
+		const std::string & getUserID();
 
-		inline void makeTemplate(json::Object & obj, const std::string & type) const;
+		void makeTemplate(json::Object & obj, const std::string & type) const;
 
-		inline std::string sms(const std::string & phone) const;
+		std::string sms(const std::string & phone) const;
 
-		inline std::string join(const std::string & id, const std::string & pw, const std::string & sms);
+		std::string join(const std::string & id, const std::string & pw, const std::string & sms);
 
-		inline std::string login(const std::string & pw) const;
+		std::string login(const std::string & pw) const;
 
-		inline std::string addFriend(const std::string & id) const;
+		std::string addFriend(const std::string & id) const;
 
-		inline std::string openSession(const std::string & to) const;
+		std::string openSession(const std::string & to) const;
 
-		inline std::string chat(const std::string & sessid, const std::string & message, const int sensitive) const;
+		std::string chat(const std::string & sessid, const std::string & message, const int sensitive) const;
 
-		inline std::string getFriendList() const;
+		std::string getFriendList() const;
 	};
 
@@ -117,11 +117,11 @@
 	{
 	public:
-		inline void makeTemplate(json::Object & obj, const std::string & type) const;
+		void makeTemplate(json::Object & obj, const std::string & type) const;
 
-		inline std::string result(const std::string & requestType, const bool status) const;
+		std::string result(const std::string & requestType, const bool status) const;
 
-		inline std::string friendList(const std::vector<SFriend> & friendList) const;
+		std::string friendList(const std::vector<SFriend> & friendList) const;
 
-		inline std::string openSession(const std::vector<std::string> & idList) const;
+		std::string openSession(const std::vector<std::string> & idList) const;
 	};
 };
@@ -156,5 +156,5 @@
 
 	for (size_t iter = 1; iter < strings.size(); iter++)
-		concat += DELIMITER + strings[iter];
+		concat += strings[iter];
 
 	return concat;
Index: /trunk/msgclnt.cpp
===================================================================
--- /trunk/msgclnt.cpp	(revision 11)
+++ /trunk/msgclnt.cpp	(revision 12)
@@ -9,15 +9,21 @@
 // --------------------------------------------------------------
 
-typedef struct SWorkerArg
+typedef struct SMessageQWorkerArg
 {
 	cf::network::tcp * socket;
 	MessageQ * messageQ;
-} SWorkerArg;
-
-int worker(void * arg)
-{
-	SWorkerArg * inst = (SWorkerArg *) arg;
-
-	Protocol::Message parser;
+} SMessageQWorkerArg;
+
+typedef struct SCallbackWorkerArg
+{
+	MessageQ * messageQ;
+	SCallback callback;
+} SCallbackWorkerArg;
+
+static int messageQworekr(void * arg)
+{
+	SMessageQWorkerArg * inst = (SMessageQWorkerArg *)arg;
+
+	Protocol::Message message;
 	cf::bin raw;
 
@@ -27,5 +33,5 @@
 		{
 			raw = inst->socket->receive();
-			parser.parse(raw.toString());
+			message.parse(raw.toString());
 		}
 		catch (cf::exception & e)
@@ -38,5 +44,5 @@
 		}
 
-		inst->messageQ->push(parser);
+		inst->messageQ->push(message);
 	}
 
@@ -46,29 +52,77 @@
 }
 
+static inline SConversation toCnversation(const Protocol::Message & message)
+{
+	SConversation c;
+
+	c.sessid = message.get<std::string>(ProtocolType::SESSION_ID);
+	c.message = message.get<std::string>(ProtocolType::MESSAGE);
+	c.sensitive = message.get<int>(ProtocolType::SENSITIVE);
+	c.isError = message.get<bool>(ProtocolType::RESULT);
+
+	c.from = message.get<std::string>(ProtocolType::FROM);
+
+	return c;
+}
+
+static inline SOpenSession toOpenSession(const Protocol::Message & message)
+{
+	SOpenSession o;
+
+	o.sessid = message.get<std::string>(ProtocolType::SESSION_ID);
+	o.idList = message.getList<std::string>(ProtocolType::ID_LIST);
+
+	return o;
+}
+
+static int callbackWorker(void * arg)
+{
+	SCallbackWorkerArg * inst = (SCallbackWorkerArg *)arg;
+
+	Protocol::Message message;
+
+	while (true)
+	{
+		message = inst->messageQ->pop(ProtocolType::CHAT, false);
+		if (message.type() != ProtocolType::NONE)
+			inst->callback.onChat(toCnversation(message));
+
+		message = inst->messageQ->pop(ProtocolType::OPEN_SESSION, false);
+		if (message.type() != ProtocolType::NONE)
+			inst->callback.onOpenSession(toOpenSession(message));
+	}
+
+	free(inst);
+
+	return 0;
+}
+
 // --------------------------------------------------------------
 
-void MessageQ::push(const Protocol::Message & parser)
+void MessageQ::push(const Protocol::Message & message)
 {
 	mutex.lock();
-	messageQ.push_back(parser);
+	messageQ.push_back(message);
 	mutex.unlock();
 }
 
-Protocol::Message MessageQ::pop(const std::string & requestType)
-{
-	while (true)
+Protocol::Message MessageQ::pop(const std::string & requestType, bool isWait)
+{
+	while (isWait)
 	{
 		SYNCHRONIZED(mutex)
 		{
-			Protocol::Message parser = messageQ.front();
-
-			if (parser.type() == requestType)
+			Protocol::Message message = messageQ.front();
+
+			if (message.type() == requestType)
 			{
 				messageQ.erase(messageQ.begin());
 
-				return parser;
+				return message;
 			}
 		}
 	}
+
+	return Protocol::Message(); // return dummy NONE
 }
 
@@ -76,5 +130,6 @@
 
 chev::chev()
-	: listener(worker)
+	: listener(messageQworekr),
+	  caller(callbackWorker)
 {
 }
@@ -96,5 +151,5 @@
 		socket.connect(host, port);
 
-		SWorkerArg * arg = (SWorkerArg *)malloc(sizeof(SWorkerArg));
+		SMessageQWorkerArg * arg = (SMessageQWorkerArg *)malloc(sizeof(SMessageQWorkerArg));
 		if (!arg)
 			return false;
@@ -203,11 +258,10 @@
 	try
 	{
+		idList.insert(idList.begin(), request.getUserID());
+
 		if (idList.size() == 2)
 			std::sort(idList.begin(), idList.end());
 
-		std::string concat = idList[0];
-
-		for (int iter = 1; iter < idList.size(); iter++)
-			concat += DELIMITER + idList[iter];
+		std::string concat = joinStrings(idList);
 
 		if (sessionMap.find(concat) == sessionMap.end())
@@ -251,16 +305,15 @@
 }
 
-SConversation chev::listen()
-{
-	SConversation c;
-	Protocol::Message message = messageQ.pop(ProtocolType::CHAT);
-
-	c.sessid    = message.get<std::string>(ProtocolType::SESSION_ID);
-	c.message   = message.get<std::string>(ProtocolType::MESSAGE);
-	c.sensitive = message.get<int>(ProtocolType::SENSITIVE);
-	c.isError   = message.get<bool>(ProtocolType::RESULT);
-
-	c.from      = message.get<std::string>(ProtocolType::FROM);
-
-	return c;
-}
+bool chev::listen(const SCallback & callback)
+{
+	SCallbackWorkerArg * arg = (SCallbackWorkerArg *)malloc(sizeof(SCallbackWorkerArg));
+	if (!arg)
+		return false;
+
+	arg->messageQ = &messageQ;
+	arg->callback = callback;
+
+	caller.start(arg);
+
+	return true;
+}
Index: /trunk/msgclnt.h
===================================================================
--- /trunk/msgclnt.h	(revision 11)
+++ /trunk/msgclnt.h	(revision 12)
@@ -21,4 +21,16 @@
 } SConversation;
 
+typedef struct SOpenSession
+{
+	std::string sessid;
+	std::vector<std::string> idList;
+} SOpenSession;
+
+typedef struct SCallback
+{
+	int(*onChat)(SConversation &);
+	int(*onOpenSession)(SOpenSession &);
+} SCallback;
+
 class MessageQ
 {
@@ -28,7 +40,7 @@
 
 public:
-	void push(const Protocol::Message & parser);
+	void push(const Protocol::Message & message);
 
-	Protocol::Message pop(const std::string & requestType);
+	Protocol::Message pop(const std::string & requestType, bool isWait = true);
 };
 
@@ -40,4 +52,5 @@
 	cf::network::tcp	socket;
 	cf::task::thread	listener;
+	cf::task::thread	caller;
 
 	MessageQ			messageQ;
@@ -68,4 +81,4 @@
 	bool tell(const SConversation & conversation);
 
-	SConversation listen();
+	bool listen(const SCallback & callback);
 };
