WtShapeGroupWidget is a Wt class used for notifying all clients from different IP addresses.
INCLUDEPATH += \ ../../Classes/CppWtServerPusher SOURCES += \ ../../Classes/CppWtServerPusher/wtserverpusher.cpp \ ../../Classes/CppWtServerPusher/wtserverpusherclient.cpp HEADERS += \ ../../Classes/CppWtServerPusher/wtserverpusher.h \ ../../Classes/CppWtServerPusher/wtserverpusherclient.h OTHER_FILES += \ ../../Classes/CppWtServerPusher/Licence.txt
//--------------------------------------------------------------------------- /* WtServerPusher, server to broadcast to all its WtServerPusherClients Copyright 2011-2015 Richel Bilderbeek This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ //--------------------------------------------------------------------------- //From http://www.richelbilderbeek.nl/CppWtServerPusher.htm //--------------------------------------------------------------------------- #ifndef WTSERVERPUSHER_H #define WTSERVERPUSHER_H #include <regex> #include <thread> #include <vector> #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Weffc++" #pragma GCC diagnostic ignored "-Wunused-but-set-parameter" #pragma GCC diagnostic ignored "-Wunused-local-typedefs" #include <boost/function.hpp> #include <boost/scoped_ptr.hpp> #include <boost/shared_ptr.hpp> #pragma GCC diagnostic pop namespace ribi { struct WtServerPusherClient; ///A Server that broadcasts its messages struct WtServerPusher { WtServerPusher(const WtServerPusher&) = delete; WtServerPusher& operator=(const WtServerPusher&) = delete; ///Let a WtServerPusherClient have its supplied function called by WtServerPusher::Run void Connect(WtServerPusherClient * const client, const boost::function<void()>& function); ///Stop a WtServerPusherClient have its supplied function called by TimePollServer::Run void Disconnect(const WtServerPusherClient* const client); ///Obtain the only instace to WtServerPusher static WtServerPusher * GetInstance(); ///Get the version of this class static std::string GetVersion(); ///Get the version history of this class static std::vector<std::string> GetVersionHistory(); ///Post calls all WtServerPusherClients' supplied functions void Post(); private: //Connection is a non-copyable POD struct Connection { Connection( const std::string& session_id, WtServerPusherClient * client, const boost::function<void()>& function) : m_session_id(session_id),m_client(client),m_function(function) { } Connection(const Connection&) = delete; Connection& operator=(const Connection&) = delete; const std::string m_session_id; WtServerPusherClient * const m_client; const boost::function<void()> m_function; }; ///WtServerPusher constructor, which is private, because WtServerPusher follows ///the Singleton design pattern WtServerPusher(); ///WtServerPusher destructor ~WtServerPusher(); ///Only let a smart pointer (that is, m_instance) delete WtServerPusher friend void boost::checked_delete<>(WtServerPusher*); ///All connections to the WtServerPusherClients std::vector<boost::shared_ptr<Connection> > m_connections; ///The WtServerPusher its only instance static boost::scoped_ptr<WtServerPusher> m_instance; ///A mutex mutable std::mutex m_mutex; }; } //~namespace ribi #endif // WTSERVERPUSHER_H
//--------------------------------------------------------------------------- /* WtServerPusher, server to broadcast to all its WtServerPusherClients Copyright 2011-2015 Richel Bilderbeek This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ //--------------------------------------------------------------------------- //From http://www.richelbilderbeek.nl/CppWtServerPusher.htm //--------------------------------------------------------------------------- #include <algorithm> #include <chrono> #include <numeric> #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Weffc++" #pragma GCC diagnostic ignored "-Wunused-but-set-parameter" #pragma GCC diagnostic ignored "-Wunused-local-typedefs" #include <boost/bind.hpp> #include <Wt/WApplication> #include <Wt/WServer> #include "wtserverpusher.h" #pragma GCC diagnostic pop boost::scoped_ptr<ribi::WtServerPusher> ribi::WtServerPusher::m_instance; ribi::WtServerPusher::WtServerPusher() : m_connections{}, m_mutex{} { } ribi::WtServerPusher::~WtServerPusher() { } void ribi::WtServerPusher::Connect( WtServerPusherClient * const client, const boost::function<void()>& function) { std::lock_guard<std::mutex> lock(m_mutex); boost::shared_ptr<Connection> connection { new Connection( Wt::WApplication::instance()->sessionId(), client, function ) }; m_connections.push_back(connection); } void ribi::WtServerPusher::Disconnect(const WtServerPusherClient* const client) { std::lock_guard<std::mutex> lock(m_mutex); m_connections.erase( std::remove_if(m_connections.begin(),m_connections.end(), [client](const boost::shared_ptr<Connection>& c) { return c->m_client == client; } )); } ribi::WtServerPusher * ribi::WtServerPusher::GetInstance() { if (!m_instance) m_instance.reset(new WtServerPusher); return m_instance.get(); } std::string ribi::WtServerPusher::GetVersion() { return "1.0"; } std::vector<std::string> ribi::WtServerPusher::GetVersionHistory() { return { "2011-08-05: version 1.0: initial version" }; } void ribi::WtServerPusher::Post() { ///Let this thread sleep, to give the other thread a chance //std::this_thread::sleep_for(std::chrono::milliseconds(10)); std::lock_guard<std::mutex> lock(m_mutex); for (auto c: m_connections) { Wt::WServer::instance()->post(c->m_session_id, c->m_function); }; }
//--------------------------------------------------------------------------- /* WtServerPusherClient, client of WtServerPusher Copyright 2011-2015 Richel Bilderbeek This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ //--------------------------------------------------------------------------- //From http://www.richelbilderbeek.nl/CppWtServerPusher.htm //--------------------------------------------------------------------------- #ifndef WTSERVERPUSHERCLIENT_H #define WTSERVERPUSHERCLIENT_H #include <string> #include <vector> namespace ribi { ///WtServerPusherClient is a client responding to WtServerPusher ///and to be used as a base class struct WtServerPusherClient { virtual ~WtServerPusherClient(); ///Get the version of this class static std::string GetVersion(); ///Get the version history of this class static std::vector<std::string> GetVersionHistory(); ///OnServerPush is called when the WtServerPusher is posted to virtual void OnServerPush() = 0; protected: ///WtServerPusherClient constructor is protected ///because it is to be used as a base class WtServerPusherClient(); private: ///Respond to the server void OnServer(); }; } //~namespace ribi #endif // WTSERVERPUSHERCLIENT_H
//--------------------------------------------------------------------------- /* WtServerPusherClient, client of WtServerPusher Copyright 2011-2015 Richel Bilderbeek This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ //--------------------------------------------------------------------------- //From http://www.richelbilderbeek.nl/CppWtServerPusher.htm //--------------------------------------------------------------------------- #include "wtserverpusherclient.h" #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Weffc++" #pragma GCC diagnostic ignored "-Wunused-but-set-parameter" #pragma GCC diagnostic ignored "-Wunused-local-typedefs" #include <boost/bind.hpp> #include <Wt/WApplication> #include "wtserverpusher.h" #pragma GCC diagnostic pop ribi::WtServerPusherClient::WtServerPusherClient() { Wt::WApplication::instance()->enableUpdates(true); WtServerPusher::GetInstance()->Connect( this,boost::bind(&ribi::WtServerPusherClient::OnServer,this)); //Never call virtual functions during construction or destruction //Scott Meyers, Effective C++, item 9 //OnServer(); } ribi::WtServerPusherClient::~WtServerPusherClient() { Wt::WApplication::instance()->enableUpdates(false); WtServerPusher::GetInstance()->Disconnect(this); } std::string ribi::WtServerPusherClient::GetVersion() { return "1.0"; } std::vector<std::string> ribi::WtServerPusherClient::GetVersionHistory() { return { "2011-07-27: version 1.0: initial version" }; } void ribi::WtServerPusherClient::OnServer() { OnServerPush(); Wt::WApplication::instance()->triggerUpdate(); }