2013-01-22 46 views
4

我使用Qt構建了一個桌面應用程序。目前,應用程序定期從遠程Web服務器上的XML文件中提取數據以填充應用程序中的各種小部件。Qt Desktop使用Node.js和Socket.io監聽端口

而是把數據的,這裏的Qt應用程序建立遠程Web服務器上的一個端口的持久連接和偵聽來自node.js中更新或「廣播」我寧願實現一個「推」環境

我已經用一個基於web的應用程序使用node.js和socket.io構建了類似的東西,所以我對此並不陌生,但我似乎無法弄清楚如何在Qt中實現這一點。我可以使用QTcpSocket連接到4000端口,我可以用node.js啓動HTTP服務器,但我似乎無法接收任何廣播的消息。

這裏缺少的是socket.io,但我不知道如何使用它或在Qt中建立所需的連接 - 所以我很茫然。

連接和端口4000聽Qt應用程序內

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->connectToHost(hostadd,3000); 

} 

在node.js中創建的服務器,然後將更新

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); 

任何建議都非常讚賞 - 是我試圖做甚至可能嗎?

編輯 - UPDATE

未能將Socket.io和WebSocket的使用C++之後,我試着用QWebView做到這一點,它的工作。如果有其他人需要幫助,我會分享我在下面所做的細節。

mainwindow.cpp

這僅僅是一個普通的Qt的GUI應用程序,其唯一目的是創建一個加載HTML文件QWebView實例。正在加載的HTML文件(在後臺)包含建立套接字連接的javascript代碼。

我創建了一個單獨的Qt類來與index.html中的javascript接口,以便處理來自服務器的響應。 More Info

#include "mainwindow.h" 
#include "ui_mainwindow.h" 

MainWindow::MainWindow(QWidget *parent) : 
QMainWindow(parent), 
ui(new Ui::MainWindow) 
{ 
    ui->setupUi(this); 

    // Set default proxy (this may not always be necessary) 
    QNetworkProxyFactory::setUseSystemConfiguration(true); 

    h = new Hello(this); 

    view = new QWebView(this); 
    view->load(QUrl("http://www.mydomain.com/startconnection.html")); 

    // I don't want the webview to show, it should run in the background 
    view->hide(); 

    frame = view->page()->mainFrame(); 
    connect(view,SIGNAL(loadFinished(bool)),this,SLOT(loadFinished(bool))); 

} 

void MainWindow::loadFinished(bool loaded) { 

    qDebug() << "Webpage Loaded? " << loaded; 

} 


MainWindow::~MainWindow() 
{ 
    delete ui; 
} 

http://www.mydomain.com/startconnection.html

這是一個被加載到Qt的頁面。它只是建立Socket.io連接到mydomain.com這是4000

<html> 
<head> 
<script type="text/javascript" src="http://www.mydomain.com:4000/socket.io/socket.io.js"></script> 
<script type="text/javascript"> 

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"); 
    }); 

} 

</script> 
</head> 
<body> 
</body> 
</html> 

/var/www/vhosts/mydomain.com/socket/server.js偵聽連接端口

這是啓動HTTP服務監聽端口4000連接的節點腳本。我以「forever」開始服務,並將所有console.info消息輸出到如下所示的日誌文件:forever -al/var/www/vhosts/mydomain。 com/connection.log start /var/www/vhosts/mydomain.dom/socket/server.js。

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); 

    }); 

}); 

希望這可以幫助別人!

+0

Qt在GITHUB上的類socket.io服務器回調函數:https://github.com/ChadyG/QtSocketIOServer – 3P5iL0WNE

回答

2

這是可能的,但是,您必須瞭解Socket.IO處理WebSocket套接字,而不是原始TCP。您的客戶端應該與服務器等進行WebSocket握手。目前發生的情況是您在客戶端創建了一個「HTTP」連接,不發送任何東西並等待發生。 (什麼都不會發生)

當然你也可以設計一個協議在原始TCP上運行,例如發送JSON的換行符/ null分隔(或者netstring封裝)blob。

+0

謝謝。我搜索了一下,發現這個[Github鏈接](https://github.com/ebshimizu/socket.io-clientpp)與爲C++編寫的Socket.io版本。需要Boost和其他依賴項。如果它能解決問題,我會給它一個答案並做出迴應。 – Marc

+0

沒有運氣。我使用Boost.org網站的指令和[這裏]的指令爲C++安裝了Boost庫(http://cpp-qt-mac-win.blogspot.com/2011/10/qt-boost-for-beginners-step-by -step.html),然後我安裝了[rapidjson](http://code.google.com/p/rapidjson/wiki/UserGuide)。我安裝了Socket.io和WebSockets。我遇到了一堆錯誤 - 讓我相信這個解決方案只適用於Microsoft Visual C++,而不適用於Qt。 – Marc

+0

請參閱編輯 - 更新我所做的工作 – Marc

0

你可以看看QWebSockets,它使用Qt實現websockets。我也構建了客戶端和服務器socket.io類,這些類將很快開放。