(C++) Wt example 3: broadcasting

January 25, 2018 · View on GitHub

 

 

 

 

 

(C++) Wt example 3: broadcasting

 

Wt example 3: broadcasting is an article about a simple Wt example in which is shown how multiple clients can respond to the same data source and be notified when needed.

 

The code shown is from the Wt git repository from 'examples/feature/broadcast/Broadcast.C'. Underneath the code it its working is explained.

 

 

This example gives a complete view of all bookkeeping necessary. Wt example 4: broadcasting shows how to use two classes to do this bookkeeping for you, resulting in shorter code.

 

 

 

 

 


 

 

This example has the following players:

  • Client: a client class
  • Server: a server class, where Clients can connect and disconnect to
  • ClientWidget: class to display a Client
  • a global Server

 

In general, the program does the following:

  • The main action is in Server::Run: every second it posts to the Clients that are connect to it
  • The Clients connect to the Server and let the Server work on them

 

First, the Server will be discussed in detail, as it is at the heart of the program. Then the ClientWidgets interplay with it is checked in more detail.

 

Server has the following member functions, which I explain in detail:

  • constructor: set the data member 'counter_' to zero, set the data member 'stop_' to false and create a boost::thread, 'thread_', that calls Server::run
  • destructor: set the data member 'stop_' to true and stop the boost::thread 'thread_'
  • Server::run: contains the action: it consists of an infinite loop, that starts with doing nothing for a second. Then Server checks if it should terminate this loop, by checking 'stop_'. The only 'real data' 'counter_' is incremented. Then, in a locked scope, all connected clients are notified. The most important line is the call of Wt::WServer::post: all clients (identified by their session ID's are post a function that these clients submitted themselves upon connecting
  • Server::connect: this method is called by the Clients: a client connecting to Server denotes that it wants to have the supplied boost::function called. In this example, the ClientWidgets want to have their ClientWidget::updateData method called: a Client simply wants to be updated when needed!
  • Server::disconnect: this method is called by a Client when it is destroyed. This method takes that Client of the list of Clients being notified
  • Server::getCount: this method is called by a Client and let it obtain the only 'real data': the value of the Server its counter. This method is called when a Client is updated

 

ClientWidget has the following member functions:

  • constructor: in it, ClientWidget connects to Server and gives it the ClientWidget::updateData function to call. Or: it lets itself be notified by letting the Server call ClientWidget::updateData. Additionaly, Wt::WApplication::enableUpdates is set to true and ClientWidget its first update is called
  • destructor: the ClientWidget notifies the Server that it does not want to be notified any longer (as it will not exist after destruction anymore. Additionaly, Wt::WApplication::enableUpdates is set to false
  • ClientWidget::updateData: the main method of ClientWidget: it requests the Server for its only data, by calling Server::getCounter, sets its text to this value and calls Wt::WApplication::triggerUpdate

 

The above being the main story, there is the following to be noted:

  • Every method in Server that writes to it, is locked by a boost::mutex. This ensures that only one thread is writing to the same data at the same time
  • Every ClientWidget sets Wt::WApplication::enableUpdates to true upon construction, calls Wt::WApplication::triggerUpdate in its most action-packed method and sets Wt::WApplication::enableUpdates to false upon destruction