ComSDK
 Указатель Классы Пространства имен Функции Переменные Определения типов Перечисления Элементы перечислений Друзья Группы Страницы
node.h
1 //========================================================================
2 #ifndef comfrm_ifc_NodeH
3 #define comfrm_ifc_NodeH
4 //========================================================================
5 #include "anymap.h"
6 #include "stringtools.h"
7 
8 #include <string>
9 #include <unordered_map>
10 #include <boost/asio.hpp>
11 #include <boost/thread/mutex.hpp>
12 //========================================================================
13 namespace com {
20  namespace interproc {
21  class Message;
22  class NodeProtocol;
23  class NodeConnection;
24  struct NodeHandshake;
25 
34  struct MAC_DLLEXPORT NodeAddress
35  {
36  NodeAddress()
37  {}
38 
42  NodeAddress(const std::string& p_machineIp, const std::string& p_appSid)
43  : m_machineIp(boost::asio::ip::address::from_string(p_machineIp))
44  , m_appSid(p_appSid)
45  {}
46 
50  NodeAddress(const boost::asio::ip::address& p_machineIp, const std::string& p_appSid)
51  : m_machineIp(p_machineIp)
52  , m_appSid(p_appSid)
53  {}
54 
58  NodeAddress(const std::string& p_appAddress)
59  {
60  std::string machineIpStr;
61  com::str::paramValueSplit(p_appAddress, '/', machineIpStr, m_appSid);
62  m_machineIp = boost::asio::ip::address::from_string(machineIpStr);
63  }
64 
68  std::string toString() const
69  {
70  return m_machineIp.to_string() + "/" + m_appSid;
71  }
72 
73  friend bool operator==(const NodeAddress& p_addr1, const NodeAddress& p_addr2);
74 
75  boost::asio::ip::address m_machineIp;
76  std::string m_appSid; // unique application's id
77  };
78 
79  // TODO: доделать!!!
80  /*
81  struct stc_NodeData
82  {
83  std::shared_ptr< NodeConnection > m_nodeConn;
84  boost::function< void (Message, CommunicationError) > m_callback;
85  };
86  */
87  //========================================================================
88  //template<>
89  //class MAC_DLLEXPORT cls_Node< Message, NodeAddress >
90  // TODO: должен быть thread-safe!
91  }
92 }
93 
94 // Определяем хэш структуры адрес для его использования в качестве ключа в unordered_map
95 namespace std
96 {
97  template <>
98  struct hash< com::interproc::NodeAddress >
99  {
100  size_t operator()(const com::interproc::NodeAddress& p_addr) const
101  {
102  if (p_addr.m_machineIp.is_v4())
103  return ((hash<unsigned long>()(p_addr.m_machineIp.to_v4().to_ulong()) >> 1)
104  ^ (hash<string>()(p_addr.m_appSid) << 1));
105  else
106  {
107  // TODO: поддерживается только v4
108  return ((hash<unsigned long>()(0) >> 1)
109  ^ (hash<string>()(p_addr.m_appSid) << 1));
110  }
111  }
112  };
113 }
114 
115 namespace com {
116  namespace interproc {
131  class MAC_DLLEXPORT Node
132  {
133  public:
134 /*
136  enum StandartDestination
137  {
138  sdSelf,
139  sdCaller,
140  sdRouter,
141  };
142 */
143 
146  {
147  ceSuccess = 0,
152  };
153 
156  {
160  };
161 
163  typedef std::function< void (std::shared_ptr< Message >, CommunicationError) > OnReplyClb;
164 
166  {
167  RemoteNodeData(std::shared_ptr< NodeConnection > p_conn, OnReplyClb p_callback)
168  : m_conn(p_conn)
169  , m_callback(p_callback)
170  {}
171 
172  std::shared_ptr< NodeConnection > m_conn;
173  OnReplyClb m_callback;
174  };
175 
176  // TODO: временно
178  {
179  BufferedMessage(const std::vector< char >& p_bytearray, const NodeAddress& p_nodeAddr, OnReplyClb p_callback)
180  : m_bytearray(p_bytearray)
181  , m_nodeAddr(p_nodeAddr)
182  , m_callback(p_callback)
183  {}
184 
185  std::vector< char > m_bytearray;
186  NodeAddress m_nodeAddr;
187  OnReplyClb m_callback;
188  };
189 
191  static const unsigned short m_port = 8221;
192 
193  public:
197  Node(const std::string& p_appId, boost::asio::io_service& p_service);
198  ~Node();
199 
203  CommunicationError deploy();
204 
209  void setDefaultCallback(OnReplyClb p_callback);
210 
217  void send(const Message& p_message, OnReplyClb p_callback = 0);
218 
222  const NodeAddress& getAddr() const;
223 
227  NodeStatus getStatus() const;
228 
229  protected:
230  void setStatus(NodeStatus p_status);
231  void onNewMessageToSend(const Message& p_message, OnReplyClb p_callback);
232  void onAccepted(std::shared_ptr< NodeConnection > p_conn, const boost::system::error_code & p_error);
233  void onConnectionClosed(std::shared_ptr< NodeConnection > p_conn);
234  void onMessageReceived(std::shared_ptr< NodeConnection > p_nodeConn, std::vector< char >& p_message);
235  void handshake(std::shared_ptr< NodeConnection > p_nodeConn, NodeHandshake p_handshake);
236  void proxyMessage(std::shared_ptr< NodeConnection > p_nodeConn, std::vector< char >& p_message);
237  void onAnyMapReceived(std::shared_ptr< NodeConnection > p_nodeConn, std::string p_appSid,
238  std::shared_ptr< Anymap > p_anymap);
239  void sendBytearrayToNode(const std::vector< char >& p_bytearray, const NodeAddress& p_nodeAddr, OnReplyClb p_callback = 0);
240  void runService();
241 
242  protected:
243  NodeAddress m_selfAddr;
244  std::string m_masterAppSid; // TODO: временно, не лучшее решение хранить здесь
245  OnReplyClb m_defaultCallback;
246  NodeStatus m_status;
247  unsigned int m_threadsCount;
248  std::shared_ptr< boost::asio::ip::tcp::acceptor > m_acceptor;
249  // TODO: переделать на unordered_multimap, так как может оказаться, что несколько нод с одинаковыми именами на одной машине
250  // TODO: решение с ... временное. Сейчас коллбэк для адреса задается в методе send, что не совсем корректно.
251  // Необходимо иметь возможность задавать коллбэк на каждое отдельное сообщение.
252  std::unordered_map< NodeAddress, RemoteNodeData > m_establishedNodes;
253  std::set< std::shared_ptr< NodeConnection > > m_anonymousNodes;
254  std::vector< BufferedMessage > m_msgBuffer;
255  boost::asio::io_service& m_service;
256  NodeProtocol* m_protocol;
257  boost::mutex m_mutex;
258  };
259  }
260 }
261 
262 //========================================================================
263 #endif
264 //========================================================================
Адрес узла
Definition: node.h:34
Definition: node_protocol.h:41
NodeAddress(const std::string &p_machineIp, const std::string &p_appSid)
Definition: node.h:42
Узел не найден
Definition: node.h:148
Класс узла
Definition: node.h:131
NodeAddress(const boost::asio::ip::address &p_machineIp, const std::string &p_appSid)
Definition: node.h:50
CommunicationError
Ошибки взаимодействия
Definition: node.h:145
Не удалось соединиться с master-узлом
Definition: node.h:149
NodeAddress(const std::string &p_appAddress)
Definition: node.h:58
Статус не задан
Definition: node.h:159
Definition: node_protocol.h:23
std::function< void(std::shared_ptr< Message >, CommunicationError) > OnReplyClb
Тип коллбэка для входящих сообщений
Definition: node.h:163
Словарь
Definition: node.h:151
Словарь
Definition: node.h:150
Master-узел
Definition: node.h:157
Сетевое сообщение
Definition: message.h:17
NodeStatus
Статус узла
Definition: node.h:155
MAC_DLLEXPORT bool paramValueSplit(const std::string &p_pair, const std::string &p_delimeter, std::string &o_param, std::string &o_value)
Definition: stringtools.cpp:102
Slave-узел
Definition: node.h:158
std::string toString() const
Definition: node.h:68