source: chevmsgr/trunk/msgclnt.cpp@ 8

Last change on this file since 8 was 8, checked in by cheese, 9 years ago

클라 UI 쪼끔 수정
프로토콜 메시지 좀 수정
클라 메시지 핸들링 추가

File size: 4.4 KB
Line 
1
2#include "msgclnt.h"
3#include "msg.hpp"
4
5#include <algorithm>
6
7#include <stdlib.h>
8
9// --------------------------------------------------------------
10
11typedef struct SWorkerArg
12{
13 cf::network::tcp * socket;
14 MessageQ * messageQ;
15} SWorkerArg;
16
17int worker(void * arg)
18{
19 SWorkerArg * inst = (SWorkerArg *) arg;
20
21 Protocol::Message parser;
22 cf::bin raw;
23
24 while (true)
25 {
26 try
27 {
28 raw = inst->socket->receive();
29 parser.parse(raw.toString());
30 }
31 catch (cf::exception & e)
32 {
33 LOG(e.stackTrace());
34
35 // closed
36 if (raw.size() == 0)
37 break;
38 }
39
40 inst->messageQ->push(parser);
41 }
42
43 free(inst);
44
45 return 0;
46}
47
48// --------------------------------------------------------------
49
50void MessageQ::push(const Protocol::Message & parser)
51{
52 SYNCHRONIZED(mutex)
53 {
54 messageQ.push_back(parser);
55 }
56}
57
58Protocol::Message MessageQ::pop(const std::string & requestType)
59{
60 while (true)
61 {
62 SYNCHRONIZED(mutex)
63 {
64 Protocol::Message parser = messageQ.front();
65
66 if (parser.type() == requestType)
67 {
68 messageQ.erase(messageQ.begin());
69
70 return parser;
71 }
72 }
73 }
74}
75
76// --------------------------------------------------------------
77
78chev::chev()
79 : listener(worker)
80{
81}
82
83chev::~chev()
84{
85 socket.close();
86}
87
88const std::string & chev::getLastError() const
89{
90 return error;
91}
92
93bool chev::connect(const std::string & host, const unsigned short port)
94{
95 try
96 {
97 socket.connect(host, port);
98
99 SWorkerArg * arg = (SWorkerArg *)malloc(sizeof(SWorkerArg));
100 if (!arg)
101 return false;
102
103 arg->socket = &socket;
104 arg->messageQ = &messageQ;
105
106 listener.start(arg);
107
108 return true;
109 }
110 catch (cf::exception & e)
111 {
112 LOG(e.what());
113
114 return false;
115 }
116}
117
118bool chev::join(const std::string & id, const std::string & pw, const std::string & sms)
119{
120 try
121 {
122 socket.send(request.join(id, pw, sms));
123
124 return messageQ.pop(ProtocolType::JOIN).get<bool>(ProtocolType::RESULT);
125 }
126 catch (cf::exception & e)
127 {
128 LOG(e.what());
129
130 return false;
131 }
132}
133
134bool chev::login(const std::string & id, const std::string & pw)
135{
136 try
137 {
138 request.setUserID(id);
139
140 socket.send(request.login(pw));
141
142 return messageQ.pop(ProtocolType::LOGIN).get<bool>(ProtocolType::RESULT);
143 }
144 catch (cf::exception & e)
145 {
146 LOG(e.what());
147
148 return false;
149 }
150}
151
152bool chev::sms(const std::string & phone)
153{
154 try
155 {
156 socket.send(request.sms(phone));
157
158 return messageQ.pop(ProtocolType::SMS).get<bool>(ProtocolType::RESULT);
159 }
160 catch (cf::exception & e)
161 {
162 LOG(e.what());
163
164 return false;
165 }
166}
167
168bool chev::addFriend(const std::string & id)
169{
170 try
171 {
172 socket.send(request.addFriend(id));
173
174 return messageQ.pop(ProtocolType::ADD_FRIEND).get<bool>(ProtocolType::RESULT);
175 }
176 catch (cf::exception & e)
177 {
178 LOG(e.what());
179
180 return false;
181 }
182}
183
184std::vector<SFriend> chev::getFriendList()
185{
186 std::vector<SFriend> friendList;
187
188 try
189 {
190 socket.send(request.getFriendList());
191
192 friendList = messageQ.pop(ProtocolType::FRIEND_LIST).getFriendList();
193 }
194 catch (cf::exception & e)
195 {
196 LOG(e.what());
197 }
198
199 return friendList;
200}
201
202std::string chev::getSessionID(std::vector<std::string> & idList)
203{
204 try
205 {
206 if (idList.size() == 2)
207 std::sort(idList.begin(), idList.end());
208
209 std::string concat = idList[0];
210
211 for (int iter = 1; iter < idList.size(); iter++)
212 concat += DELIMITER + idList[iter];
213
214 if (sessionMap.find(concat) == sessionMap.end())
215 {
216 socket.send(request.openSession(concat));
217
218 Protocol::Message message = messageQ.pop(ProtocolType::SESSION_ID);
219
220 if (!message.get<bool>(ProtocolType::RESULT))
221 THROW_EXCEPTION("failed to open session id");
222
223 sessionMap[concat] = message.get<std::string>(ProtocolType::SESSION_ID);
224 }
225
226 return sessionMap[concat];
227 }
228 catch (cf::exception & e)
229 {
230 LOG(e.what());
231
232 return "";
233 }
234}
235
236bool chev::tell(const SConversation & conversation)
237{
238 try
239 {
240 const SConversation & c = conversation;
241
242 socket.send(request.chat(c.sessid, c.message, c.sensitive));
243
244 return messageQ.pop(ProtocolType::CHAT).get<bool>(ProtocolType::RESULT);
245 }
246 catch (cf::exception & e)
247 {
248 LOG(e.what());
249
250 return false;
251 }
252}
253
254SConversation chev::listen()
255{
256 SConversation c;
257 Protocol::Message message = messageQ.pop(ProtocolType::CHAT);
258
259 c.sessid = message.get<std::string>(ProtocolType::SESSION_ID);
260 c.message = message.get<std::string>(ProtocolType::MESSAGE);
261 c.sensitive = message.get<int>(ProtocolType::SENSITIVE);
262 c.isError = message.get<bool>(ProtocolType::RESULT);
263
264 c.from = message.get<std::string>(ProtocolType::FROM);
265
266 return c;
267}
Note: See TracBrowser for help on using the repository browser.