title: Qt Desktop listening to ports using Node.js and Socket.io
body: <p>I built a desktop application using Qt.  Currently, the application pulls data at regular intervals from XML files on a remote web server to populate various widgets in the application.  </p>
  
  <p>Instead of pulling the data, I would rather implement a "push" environment where the Qt application establishes a persistent connection to a port on the remote web server and listens for updates or "broadcasts" from node.js.</p>
  
  <p>I have already built something similar with a web-based application using node.js and socket.io, so I'm not new to this, but I can't seem to figure out how to accomplish this in Qt.  I can make a connection to port 4000 using QTcpSocket and I can start the HTTP server with node.js, but I can't seem to pick up any messages that are broadcast.  </p>
  
  <p>The one piece that's missing here is socket.io, but I don't know how to use it or establish the required connection inside Qt -- so I'm at a loss.</p>
  
  <p><strong>Connect and Listen on port 4000 inside Qt Application</strong></p>
  
  <pre><code>void MainWindow::connectTcp() {
  
  client = new QTcpSocket(this);
  QHostAddress hostadd("myIPaddress");
  connect(client,SIGNAL(connected()),this,SLOT(isConnected()));
      connect(client,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(connectionError(QAbstractSocket::SocketError)));
  connect(client, SIGNAL(readyRead()), this, SLOT(readTcpData()));
  client-&gt;connectToHost(hostadd,3000);
  
  } 
  </code></pre>
  
  <p><strong>Create server in node.js and send updates</strong></p>
  
  <pre><code>var http = require('http'); 
  var url = require('url');
  var msg = '';
  
  var port = 4000;
  /* path to socket.io */
  var path = '/path/to/node_modules/socket.io';
  
  var server = http.createServer(function (req, res) {
  
          req.on('data', function (d) {
              data += d;
          });
          req.on('end',function(){
              msg = data;
      res.writeHead(200,{'Content-Type':'text/plain'});
      res.write(msg);
      res.end();
      console.log('SEND DATA: ',msg);
          });
  
  }).listen(port);
  </code></pre>
  
  <p>Any suggestions are greatly appreciated -- is what I'm trying to do even possible?</p>
  
  <p><strong>EDIT -- UPDATE</strong></p>
  
  <p>After failing to incorporate Socket.io and WebSocket using C++, I tried to do it with QWebView and it worked.  I'm sharing the details of what I did below in case anyone else needs help.  </p>
  
  <p><strong>mainwindow.cpp</strong></p>
  
  <p>This is just a generic Qt Gui Application whose only purpose is to create a QWebView instance that loads an HTML file.  The HTML file that is being loaded (in the background) contains the javascript code that establishes the socket connection.</p>
  
  <p>I created a separate Qt class to interface with the javascript in index.html to act on the responses from the server. <a href="http://doc.qt.digia.com/4.7-snapshot/qtwebkit-bridge.html" rel="nofollow">More Info</a></p>
  
  <pre><code>#include "mainwindow.h"
  #include "ui_mainwindow.h"
  
  MainWindow::MainWindow(QWidget *parent) :
  QMainWindow(parent),
  ui(new Ui::MainWindow)
  {
      ui-&gt;setupUi(this);
  
      // Set default proxy (this may not always be necessary)
      QNetworkProxyFactory::setUseSystemConfiguration(true);
  
      h = new Hello(this);
  
      view = new QWebView(this);
      view-&gt;load(QUrl("http://www.mydomain.com/startconnection.html"));
  
      // I don't want the webview to show, it should run in the background
      view-&gt;hide(); 
  
      frame = view-&gt;page()-&gt;mainFrame();
      connect(view,SIGNAL(loadFinished(bool)),this,SLOT(loadFinished(bool)));
  
  }
  
  void MainWindow::loadFinished(bool loaded) {
  
      qDebug() &lt;&lt; "Webpage Loaded? " &lt;&lt; loaded;
  
  }
  
  
  MainWindow::~MainWindow()
  {
      delete ui;
  }
  </code></pre>
  
  <p><strong>http://www.mydomain.com/startconnection.html</strong></p>
  
  <p>This is the page that gets loaded into Qt.  It simply establishes the Socket.io connection to mydomain.com which is listening for connections on port 4000</p>
  
  <pre><code>&lt;html&gt;
  &lt;head&gt;
  &lt;script type="text/javascript" src="http://www.mydomain.com:4000/socket.io/socket.io.js"&gt;&lt;/script&gt; 
  &lt;script type="text/javascript"&gt;
  
  var socket;
  
  window.onload = onLoad;
  
  function onLoad() {
  
      socket = io.connect('http://www.mydomain.com:4000');
  
      socket.on('connect', function(){
          alert("Connected To Socket");
      });
  
      socket.on('message',function(data) {
          alert("Here Comes A Message From The Server");
      });
  
  }
  
  &lt;/script&gt;
  &lt;/head&gt;
  &lt;body&gt;
  &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p><strong>/var/www/vhosts/mydomain.com/socket/server.js</strong></p>
  
  <p>This is the node script that starts the HTTP service listening for connections on port 4000.  I started the service with "forever" and output all console.info messages to a log file like this: forever -al /var/www/vhosts/mydomain.com/connection.log start /var/www/vhosts/mydomain.dom/socket/server.js. </p>
  
  <pre><code>var http = require('http'); 
  var url = require('url');
  var qs = require('querystring');
  var child_process = require('child_process');
  var theSockets = {};
  
  /* listening port */
  var port = 4000;
  /* path to socket.io on server */
  var path = '/var/www/vhosts/mydomain.com/httpdocs/server/node_modules/socket.io';
  
  var server = http.createServer(function (req, res) {
  
           var data = '';
           var msg = '';
  
          req.on('data', function (d) {
                  data += d;
          });
  
          req.on('end',function(){
              msg = data;
              io.sockets.emit('message',msg);
              res.end();
          });
  
          }
  
          res.end();
  
  }).listen(port);
  
  var io = require(path).listen(server);
  
  io.sockets.on('connection', function(socket) {
  
      var d = new Date();
      console.log('JOINED SOCKET '+d.toLocaleString()+' SOCKET ID '+socket.id);
  
      socket.on('disconnect',function() {
  
      var d = new Date();
      console.log('EXITED SOCKET '+d.toLocaleString()+' SOCKET ID '+socket.id);
  
      });
  
  });
  </code></pre>
  
  <p>Hope this helps someone!</p>