UniSet  2.24.2
UWebSocketGate.h
1 /*
2  * Copyright (c) 2017 Pavel Vainerman.
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as
6  * published by the Free Software Foundation, version 2.1.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  * Lesser General Lesser Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  */
16 // --------------------------------------------------------------------------
20 // --------------------------------------------------------------------------
21 #ifndef UWebSocketGate_H_
22 #define UWebSocketGate_H_
23 // --------------------------------------------------------------------------
24 #include <queue>
25 #include <memory>
26 #include <mutex>
27 #include <condition_variable>
28 #include <chrono>
29 #include <ev++.h>
30 #include <sigc++/sigc++.h>
31 #include <Poco/JSON/Object.h>
32 #include <Poco/Net/WebSocket.h>
33 #include "UniSetTypes.h"
34 #include "LogAgregator.h"
35 #include "UniSetObject.h"
36 #include "DebugStream.h"
37 #include "SharedMemory.h"
38 #include "SMInterface.h"
39 #include "EventLoopServer.h"
40 #include "UTCPStream.h"
41 #include "UHttpRequestHandler.h"
42 #include "UHttpServer.h"
43 #include "UTCPCore.h"
44 #include "RunLock.h"
45 // -------------------------------------------------------------------------
46 namespace uniset
47 {
48  //------------------------------------------------------------------------------------------
188  public UniSetObject,
189  public EventLoopServer
190 #ifndef DISABLE_REST_API
191  , public Poco::Net::HTTPRequestHandler
192 #endif
193  {
194  public:
195  UWebSocketGate( uniset::ObjectId id, xmlNode* cnode
196  , uniset::ObjectId shmID
197  , const std::shared_ptr<SharedMemory>& ic = nullptr
198  , const std::string& prefix = "-ws" );
199 
200  virtual ~UWebSocketGate();
201 
203  static std::shared_ptr<UWebSocketGate> init_wsgate( int argc, const char* const* argv
204  , uniset::ObjectId shmID
205  , const std::shared_ptr<SharedMemory>& ic = nullptr
206  , const std::string& prefix = "ws-" );
207 
209  static void help_print();
210 
211  inline std::shared_ptr<DebugStream> log()
212  {
213  return mylog;
214  }
215  inline std::shared_ptr<uniset::LogAgregator> logAgregator() noexcept
216  {
217  return loga;
218  }
219 
220 #ifndef DISABLE_REST_API
221  virtual void handleRequest( Poco::Net::HTTPServerRequest& req, Poco::Net::HTTPServerResponse& resp ) override;
222  void onWebSocketSession( Poco::Net::HTTPServerRequest& req, Poco::Net::HTTPServerResponse& resp );
223 #endif
224 
225  protected:
226 
227  class UWebSocket;
228 
229  virtual bool activateObject() override;
230  virtual bool deactivateObject() override;
231  virtual void sysCommand( const uniset::SystemMessage* sm ) override;
232  void run( bool async );
233  virtual void evfinish() override;
234  virtual void evprepare() override;
235  void onCheckBuffer( ev::timer& t, int revents );
236  void onActivate( ev::async& watcher, int revents ) ;
237  void onCommand( ev::async& watcher, int revents );
238 
239 #ifndef DISABLE_REST_API
240  void httpWebSocketPage( std::ostream& out, Poco::Net::HTTPServerRequest& req, Poco::Net::HTTPServerResponse& resp );
241  void httpWebSocketConnectPage(std::ostream& out, Poco::Net::HTTPServerRequest& req,
242  Poco::Net::HTTPServerResponse& resp, const std::string& params );
243 
244  std::shared_ptr<UWebSocket> newWebSocket(Poco::Net::HTTPServerRequest* req, Poco::Net::HTTPServerResponse* resp, const Poco::URI::QueryParameters& qp );
245  void delWebSocket( std::shared_ptr<UWebSocket>& ws );
246 
247  Poco::JSON::Object::Ptr respError( Poco::Net::HTTPServerResponse& resp, Poco::Net::HTTPResponse::HTTPStatus s, const std::string& message );
248  void makeResponseAccessHeader( Poco::Net::HTTPServerResponse& resp );
249 #endif
250  void terminate();
251 
252  ev::async wsactivate; // активация WebSocket-ов
253  std::shared_ptr<ev::async> wscmd;
254 
255  void checkMessages( ev::timer& t, int revents );
256  virtual void sensorInfo( const uniset::SensorMessage* sm ) override;
257  virtual uniset::SimpleInfo* getInfo( const char* userparam = 0 ) override;
258  ev::timer iocheck;
259  double check_sec = { 0.05 };
260  int maxMessagesProcessing = { 100 };
261 
262  std::shared_ptr<DebugStream> mylog;
263  std::shared_ptr<uniset::LogAgregator> loga;
264  std::shared_ptr<SMInterface> shm;
265  std::unique_ptr<uniset::RunLock> runlock;
266 
267  std::shared_ptr<uniset::LogServer> logserv;
268  std::string logserv_host = {""};
269  int logserv_port = {0};
270 
271 #ifndef DISABLE_REST_API
272  std::shared_ptr<Poco::Net::HTTPServer> httpserv;
273  std::string httpHost = { "" };
274  int httpPort = { 0 };
275  std::string httpCORS_allow = { "*" };
276 
277  double wsHeartbeatTime_sec = { 3.0 };
278  double wsSendTime_sec = { 0.5 };
279  size_t wsMaxSend = { 5000 };
280  size_t wsMaxCmd = { 200 };
281 
282  static Poco::JSON::Object::Ptr to_json( const uniset::SensorMessage* sm, const std::string& err );
283  static Poco::JSON::Object::Ptr error_to_json( const std::string& err );
284 
292  class UWebSocket:
293  public Poco::Net::WebSocket
294  {
295  public:
296  UWebSocket( Poco::Net::HTTPServerRequest* req,
297  Poco::Net::HTTPServerResponse* resp);
298 
299  virtual ~UWebSocket();
300 
301  std::string getInfo() const noexcept;
302 
303  bool isActive();
304  void set( ev::dynamic_loop& loop, std::shared_ptr<ev::async> a );
305 
306  void send( ev::timer& t, int revents );
307  void ping( ev::timer& t, int revents );
308  void read( ev::io& io, int revents );
309 
310  struct sinfo
311  {
312  std::string err; // ошибка при работе с датчиком (например при заказе)
314  std::string cmd = "";
315  long value = { 0 }; // set value
316  };
317 
318 
319  void ask( uniset::ObjectId id );
320  void del( uniset::ObjectId id );
321  void get( uniset::ObjectId id );
322  void set( uniset::ObjectId id, long value );
323  void sensorInfo( const uniset::SensorMessage* sm );
324  void doCommand( const std::shared_ptr<SMInterface>& ui );
325  static Poco::JSON::Object::Ptr to_short_json( sinfo* si );
326 
327  void term();
328 
329  void waitCompletion();
330 
331  // настройка
332  void setHearbeatTime( const double& sec );
333  void setSendPeriod( const double& sec );
334  void setMaxSendCount( size_t val );
335  void setMaxCmdCount( size_t val );
336 
337  std::shared_ptr<DebugStream> mylog;
338 
339  protected:
340 
341  void write();
342  void sendResponse( sinfo& si );
343  void sendShortResponse( sinfo& si );
344  void onCommand( const std::string& cmd );
345  void sendError( const std::string& message );
346 
347  ev::timer iosend;
348  double send_sec = { 0.5 };
349  size_t maxsend = { 5000 };
350  size_t maxcmd = { 200 };
351  const int Kbuf = { 10 }; // коэффициент для буфера сообщений (maxsend умножается на Kbuf)
352 
353  ev::timer ioping;
354  double ping_sec = { 3.0 };
355  static const std::string ping_str;
356 
357  ev::io iorecv;
358  char rbuf[32 * 1024];
359  timeout_t recvTimeout = { 200 }; // msec
360  std::shared_ptr<ev::async> cmdsignal;
361 
362  std::mutex finishmut;
363  std::condition_variable finish;
364 
365  std::atomic_bool cancelled = { false };
366 
367  std::unordered_map<uniset::ObjectId, sinfo> smap;
368  std::queue<sinfo> qcmd; // очередь команд
369 
370  Poco::Net::HTTPServerRequest* req;
371  Poco::Net::HTTPServerResponse* resp;
372 
373  // очередь json-на отправку
374  std::queue<Poco::JSON::Object::Ptr> jbuf;
375 
376  // очередь данных на посылку..
377  std::queue<uniset::UTCPCore::Buffer*> wbuf;
378  size_t maxsize; // рассчитывается сходя из max_send (см. конструктор)
379  };
380 
382  {
383  public:
384 
385  UWebSocketGuard( std::shared_ptr<UWebSocket>& s, UWebSocketGate* g ):
386  ws(s), wsgate(g) {}
387 
388  ~UWebSocketGuard()
389  {
390  wsgate->delWebSocket(ws);
391  }
392 
393 
394  private:
395  std::shared_ptr<UWebSocket> ws;
396  UWebSocketGate* wsgate;
397  };
398 
399  friend class UWebSocketGuard;
400 
401  std::list<std::shared_ptr<UWebSocket>> wsocks;
402  uniset::uniset_rwmutex wsocksMutex;
403  size_t maxwsocks = { 50 }; // максимальное количество websocket-ов
404 
405 
407  public Poco::Net::HTTPRequestHandlerFactory
408  {
409  public:
412 
413  virtual Poco::Net::HTTPRequestHandler* createRequestHandler( const Poco::Net::HTTPServerRequest& req ) override;
414 
415  private:
416  UWebSocketGate* wsgate;
417  };
418 #endif
419 
420  private:
421 
422  };
423  // ----------------------------------------------------------------------------------
424 } // end of namespace uniset
425 //------------------------------------------------------------------------------------------
426 #endif
The EventLoopServer class Реализация общей части всех процессов использующих libev....
Definition: EventLoopServer.h:18
Definition: MessageType.h:127
Definition: MessageType.h:171
Definition: UWebSocketGate.h:382
Definition: UWebSocketGate.h:294
timeout_t recvTimeout
Definition: UWebSocketGate.h:359
Definition: UWebSocketGate.h:193
virtual bool activateObject() override
Активизация объекта (переопределяется для необходимых действий после активизации)
Definition: UWebSocketGate.cc:631
static std::shared_ptr< UWebSocketGate > init_wsgate(int argc, const char *const *argv, uniset::ObjectId shmID, const std::shared_ptr< SharedMemory > &ic=nullptr, const std::string &prefix="ws-")
Definition: UWebSocketGate.cc:317
virtual bool deactivateObject() override
Деактивация объекта (переопределяется для необходимых действий при завершении работы)
Definition: UWebSocketGate.cc:621
static void help_print()
Definition: UWebSocketGate.cc:333
Definition: UniSetObject.h:80
std::shared_ptr< UInterface > ui
Definition: UniSetObject.h:136
Definition: Mutex.h:32
Definition: CommonEventLoop.h:15
const ObjectId DefaultObjectId
Definition: UniSetTypes.h:70
long ObjectId
Definition: UniSetTypes_i.idl:30
Definition: UniSetTypes_i.idl:65
Definition: UWebSocketGate.h:311