source: chevmsgr/trunk/msgclnt.cpp@ 9

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

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