source: chevmsgr/trunk/msgclnt.cpp@ 10

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

mutex lock/unlock 사용 시 버그 발생하는 부분 롤백 ㅠㅠ

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