source: chevmsgr/trunk/msgclnt.cpp@ 6

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

modify client interface and message protocol

File size: 4.2 KB
Line 
1
2#include "msgclnt.h"
3#include "msg.hpp"
4
5#include <stdlib.h>
6
7// --------------------------------------------------------------
8
9typedef struct SWorkerArg
10{
11 cf::network::tcp * socket;
12 MessageQ * messageQ;
13} SWorkerArg;
14
15int worker(void * arg)
16{
17 SWorkerArg * inst = (SWorkerArg *) arg;
18
19 Protocol::Message parser;
20 cf::bin raw;
21
22 while (true)
23 {
24 try
25 {
26 raw = inst->socket->receive();
27 parser.parse(raw.toString());
28 }
29 catch (cf::exception & e)
30 {
31 LOG(e.stackTrace());
32
33 // closed
34 if (raw.size() == 0)
35 break;
36 }
37
38 inst->messageQ->push(parser);
39 }
40
41 free(inst);
42
43 return 0;
44}
45
46// --------------------------------------------------------------
47
48void MessageQ::push(const Protocol::Message & parser)
49{
50 SYNCHRONIZED(mutex)
51 {
52 messageQ.push_back(parser);
53 }
54}
55
56Protocol::Message MessageQ::pop(const std::string & requestType)
57{
58 while (true)
59 {
60 SYNCHRONIZED(mutex)
61 {
62 Protocol::Message parser = messageQ.front();
63
64 if (parser.type() == requestType)
65 {
66 messageQ.erase(messageQ.begin());
67
68 return parser;
69 }
70 }
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 try
185 {
186 socket.send(request.getFriendList());
187 }
188 catch (cf::exception & e)
189 {
190 LOG(e.what());
191 }
192 return std::vector<SFriend>();
193}
194
195std::string chev::getSessionID(const std::vector<std::string> & idList)
196{
197 try
198 {
199 std::string concat = idList[0];
200
201 for (int iter = 1 ; iter < idList.size() ; iter++)
202 concat += "," + idList[iter];
203
204 if (sessionMap.find(concat) == sessionMap.end())
205 {
206 socket.send(request.openSession(concat));
207
208 std::string response = socket.receive().toString();
209 Protocol::Message parser;
210 parser.parse(response);
211
212 if (!parser.get<bool>("result"))
213 THROW_EXCEPTION("failed to open session id");
214
215 sessionMap[concat] = parser.get<std::string>("sess-id");
216 }
217
218 return sessionMap[concat];
219 }
220 catch (cf::exception & e)
221 {
222 LOG(e.what());
223
224 return "";
225 }
226}
227
228bool chev::tell(const SConversation & conversation)
229{
230 try
231 {
232 const SConversation & c = conversation;
233
234 socket.send(request.chat(c.sessid, c.message, c.sensitive));
235
236 return messageQ.pop(ProtocolType::CHAT).get<bool>(ProtocolType::RESULT);
237 }
238 catch (cf::exception & e)
239 {
240 LOG(e.what());
241
242 return false;
243 }
244}
245
246SConversation chev::listen()
247{
248 SConversation c;
249 Protocol::Message parser = messageQ.pop(ProtocolType::CHAT);
250
251 c.sessid = parser.get<std::string>(ProtocolType::SESSION_ID);
252 c.message = parser.get<std::string>(ProtocolType::MESSAGE);
253 c.sensitive = parser.get<int>(ProtocolType::SENSITIVE);
254 c.isError = parser.get<bool>(ProtocolType::RESULT);
255
256 c.from = parser.get<std::string>(ProtocolType::FROM);
257
258 return c;
259}
Note: See TracBrowser for help on using the repository browser.