4

Qt を使用してデスクトップ アプリケーションを作成しました。現在、アプリケーションは、リモート Web サーバー上の XML ファイルから定期的にデータを取得して、アプリケーション内のさまざまなウィジェットにデータを取り込みます。

データをプルする代わりに、Qt アプリケーションがリモート Web サーバー上のポートへの永続的な接続を確立し、node.js からの更新または「ブロードキャスト」をリッスンする「プッシュ」環境を実装したいと思います。

node.jsとsocket.ioを使用してWebベースのアプリケーションで同様のものをすでに構築しているので、これは初めてではありませんが、Qtでこれを達成する方法を理解できないようです. QTcpSocket を使用してポート 4000 に接続でき、node.js で HTTP サーバーを起動できますが、ブロードキャストされたメッセージを取得できないようです。

ここに欠けているのは socket.io ですが、それを使用する方法や Qt 内で必要な接続を確立する方法がわからないため、途方に暮れています。

Qt アプリケーション内のポート 4000 で接続してリッスンする

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

どんな提案でも大歓迎です-私がやろうとしていることは可能ですか?

編集 -- 更新

C++ を使用して Socket.io と WebSocket の組み込みに失敗した後、QWebView でそれを実行しようとしましたが、うまくいきました。他の誰かが助けを必要とする場合に備えて、私が行ったことの詳細を以下に共有しています。

メインウィンドウ.cpp

これは、HTML ファイルをロードする QWebView インスタンスを作成することだけを目的とした汎用の Qt Gui アプリケーションです。(バックグラウンドで) ロードされている HTML ファイルには、ソケット接続を確立する JavaScript コードが含まれています。

サーバーからの応答に基づいて動作するように index.html の javascript とやり取りする別の Qt クラスを作成しました。より詳しい情報

#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 に読み込まれるページです。ポート 4000 で接続をリッスンしている mydomain.com への Socket.io 接続を確立するだけです。

<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

これは、ポート 4000 で接続をリッスンする HTTP サービスを開始するノード スクリプトです。サービスを「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);

    });

});

これが誰かを助けることを願っています!

4

2 に答える 2

2

はい、可能ですが、生のTCPではなく、Socket.IOがWebSocketソケットを扱うことを理解する必要があります。クライアントはサーバーなどと WebSocket ハンドシェイクを行う必要があります。現在起こっていることは、クライアント側で「HTTP」接続を作成し、何も送信せず、何かが起こるのを待つことです。(何も起こりません。)

もちろん、生の TCP の上で実行するプロトコルを考案することもできます。たとえば、改行/null で区切られた (またはネット文字列でカプセル化された) JSON のブロブを送信します。

于 2013-01-22T17:54:28.467 に答える
1

Qt を使用して websocket を実装するQWebSocketsを見ることができます。また、クライアントとサーバーの両方の socket.io クラスを作成しました。これはまもなくオープン ソース化される予定です。

編集:ここで見つけてください

于 2016-02-15T21:25:42.713 に答える