Samchon Framework for CPP  1.0.0
Client.cpp
1 #include <samchon/protocol/service/Client.hpp>
2 # include <samchon/protocol/service/Server.hpp>
3 # include <samchon/protocol/service/User.hpp>
4 # include <samchon/protocol/service/Service.hpp>
5 
6 #include <mutex>
7 #include <boost/asio.hpp>
8 #include <boost/bind.hpp>
9 
10 #include <samchon/library/SQLi.hpp>
11 #include <samchon/library/SQLStatement.hpp>
12 #include <samchon/library/XML.hpp>
13 #include <samchon/library/Semaphore.hpp>
14 
15 #include <samchon/protocol/Invoke.hpp>
16 
17 using namespace std;
18 
19 using namespace boost::asio;
20 using namespace boost::asio::ip;
21 
22 using namespace samchon;
23 using namespace samchon::library;
24 using namespace samchon::protocol;
25 using namespace samchon::protocol::service;
26 
27 /* --------------------------------------------------------
28  CONSTRUCTORS
29 -------------------------------------------------------- */
30 Client::Client(User *user)
31  : super()
32 {
33  this->user = user;
34 }
35 Client::~Client()
36 {
37  delete service;
38 }
39 
40 auto Client::__keepAlive() -> ServiceKeeper
41 {
42  return ServiceKeeper(user, this);
43 }
44 
45 /* --------------------------------------------------------
46  GETTERS
47 -------------------------------------------------------- */
48 auto Client::getUser() const -> User*
49 {
50  return user;
51 }
52 auto Client::getService() const -> Service*
53 {
54  return service;
55 }
56 auto Client::getNo() const -> size_t
57 {
58  return no;
59 }
60 
61 /* --------------------------------------------------------
62  HANDLING MESSAGE
63 -------------------------------------------------------- */
64 void Client::sendData(shared_ptr<Invoke> invoke)
65 {
66  KEEP_CLIENT_ALIVE;
67 
68  ByteArray header;
69  string &msg = invoke->toXML()->toString();
70  boost::system::error_code error;
71 
72  header.push_back(129);
73  if (msg.size() < 126)
74  {
75  //DO NOTHING
76  }
77  else if(header.size() <= 65535)
78  {
79  header.push_back(126);
80  header.writeReversely((unsigned short)msg.size());
81  }
82  else
83  {
84  header.push_back(127);
85  header.writeReversely((unsigned long long)msg.size());
86  }
87 
88  unique_lock<mutex> uk(*sendMtx);
89  socket->write_some(boost::asio::buffer(header), error);
90  socket->write_some(boost::asio::buffer(msg), error);
91 
92  //super::sendData(invoke);
93 }
94 void Client::replyData(shared_ptr<Invoke> invoke)
95 {
96  std::string &listener = invoke->getListener();
97 
98  if (listener == "notifyService")
99  {
100  std::string &name = invoke->at(0)->getValue<string>();
101 
102  constructService(name);
103  }
104  else if (listener == "login" || listener == "join" || listener == "logout")
105  {
106  user->replyData(invoke);
107  }
108  else
109  {
110  if (service != nullptr)
111  {
112  thread([this, invoke]()
113  {
114  KEEP_CLIENT_ALIVE;
115  UniqueAcquire acquire(*user->getSemaphore());
116 
117  service->replyData(invoke);
118  }).detach();
119  }
120  }
121 }
122 
123 void Client::constructService(const std::string &name)
124 {
125  if (service != nullptr)
126  return;
127 
128  int authority;
129  bool satisfactory;
130 
131  service = createService(name);
132  if (service == nullptr)
133  {
134  authority = 0;
135  satisfactory = false;
136  }
137  else
138  {
139  authority = user->getAuthority();
140  satisfactory = (authority >= service->REQUIRE_AUTHORITY());
141  }
142  service->name = name;
143 
144  shared_ptr<Invoke> replyInvoke(new Invoke("notifyAuthority"));
145  replyInvoke->emplace_back( new InvokeParameter("authority", authority) );
146  replyInvoke->emplace_back( new InvokeParameter("satisfactory", satisfactory) );
147 
148  sendData(replyInvoke);
149 }
virtual void replyData(std::shared_ptr< Invoke >) override
Reply a message.
Definition: User.cpp:150
virtual void replyData(std::shared_ptr< Invoke >)
Reply a message.
virtual auto REQUIRE_AUTHORITY() const -> int=NULL
Required authority to access the service.
void sendData(std::shared_ptr< Invoke >)
Send Invoke message to (physical) client.
Definition: Client.cpp:64
auto getSemaphore() const -> library::Semaphore *
Get semaphore.
Definition: User.cpp:55
Definition: RWMutex.hpp:4
auto getNo() const -> size_t
Get no.
Definition: Client.cpp:56
Package of libraries.
Definition: library.hpp:84
auto getAuthority() const -> int
Get authority of user.
Definition: User.cpp:50
User containing Client(s) with session-id.
Definition: User.hpp:56
void writeReversely(const T &val)
Write a data.
Definition: ByteArray.hpp:193
Unique acquire from a Semaphore.
void replyData(std::shared_ptr< Invoke >)
Reply Invoke message from (physical) client.
void constructService(const std::string &)
Construct Service.
Definition: Client.cpp:123
std::mutex * sendMtx
A mutex for sending message.
Definition: IClient.hpp:65
Package of cloud service as a server.
Package of network protocol and libraries.
Definition: protocol.hpp:185
size_t no
A sequence number of the Client in an User.
Definition: Client.hpp:64
An interface for a client.
Definition: IClient.hpp:53
auto getUser() const -> User *
Get User.
Definition: Client.cpp:48
Standard message of network I/O.
Definition: Invoke.hpp:47
Binary data class.
Definition: ByteArray.hpp:30
Socket * socket
Socket for network I/O.
Definition: IClient.hpp:60
User * user
An User of the Client.
Definition: Client.hpp:59
Service * service
A Service belongs to the Client.
Definition: Client.hpp:69
A parameter of an Invoke.
A keeper blocking destrunction of User and Client.
virtual auto createService(const std::string &) -> Service *=0
Factory method of Service.
std::string name
A name represents a Service.
Definition: Service.hpp:67
Top level namespace of products built from samchon.
Definition: ByteArray.hpp:7
auto getService() const -> Service *
Get Service.
Definition: Client.cpp:52