2017-11-28 22 views
1

私は、C++で書かれたアプリケーションとPHPで書かれたWebサーバの間の通信を実装しなければなりませんでした。 基本的な考え方は、C++アプリケーションでソケットを作成し、それをバインドしてPHPへの接続を待ち受けることでした。 PHPはTCPを介してデータを要求するメッセージを送信し、C++は答えを返信します。単一ヘッダー要求、単一文字列(JSON)応答。 これまでのところ、とても良いです。 これは私がPHP側に使用するコードです:同じマシンでのソケット接続、PHPからC++、そしてバック

<?php 
error_reporting(E_ALL); 

$service_port = 8080; 
$address = 'localhost'; 


$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); 
if ($socket === false) { 
    echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n"; 
} 

echo "Attempting to connect to '$address' on port '$service_port'..."; 
$result = socket_connect($socket, $address, $service_port); 
if ($result === false) { 
    echo "socket_connect() failed.\nReason: ($result) " . socket_strerror(socket_last_error($socket)) . "\n"; 
} 


$in = "request1"; 

$out = ''; 

socket_write($socket, $in, strlen($in)); 

$buf = 'This is my buffer.'; 
if (false !== ($bytes = socket_recv($socket, $buf, 2048, MSG_WAITALL))) { 
    echo "Read $bytes bytes from socket_recv(). Closing socket..."; 
} else { 
    echo "socket_recv() failed; reason: " . socket_strerror(socket_last_error($socket)) . "\n"; 
} 
socket_close($socket); 

echo $buf . "\n"; 
//elaborate the $buf 
?> 

今、私はCで、また、データの自動更新を実装したいと思い++(サーバー側)データとPHPの送信側(クライアント側)収集する。 データの更新は1分ごとに行う必要があります。 悲しいことに、私はWeb開発の経験があまりないので、そのことについていくつかのアドバイスをお願いします。

私ができる最も簡単なことは、既知のメッセージが受信されるまでPHPコードをループすることでした。私が直面した問題は、ループが終了してPHPスクリプトが終了するまでデータを取得しないということです。 この問題を解決するために、私はPHPソケットを非ブロックに設定しようとしました。 socket_recvオプションMSG_WAITALLをMSG_DONTWAITに置き換えましたが、何も変更されませんでした。その後、私はPHPスクリプトから抜け出そうとしましたが、毎秒データを取得するためにはサイクルを繰り返す必要があるため、実行できません。 さらに、ループサイクル中に、PHPが実行されているApacheサーバーが503エラー、Server Unavailableを取得しているという別の問題が発生しました。 私はなぜそれが起こるか、受信したメッセージバッファがいっぱいであるか、またはスクリプトのリソースが多すぎるかどうかわかりません。 私の経験不足のため、私はなぜそれを理解できません。 私は必要なものを実行するのに良いライブラリーがあることを知っていますが、私は組み込みマシンで作業していますので、基本ライブラリーでは動作しません。

ApacheサーバでPHPを実行して、C++アプリケーションからタイムデータを取得するにはどうすればよいですか?私は何を見落としていますか? ご協力いただきありがとうございます。

編集:修辞的な質問が削除されました。

+0

[なぜ私が正しい方向に向くのは実際の問題ではありません]](https://meta.stackexchange.com/questions/226103/are-point-me-in-the-right-direction-質問可) –

答えて

2

tcp/ipを介して別のプロセスからデータを取得するためにphpを使用すると、apache経由で実行されるphpスクリプトからtcp/ipソケットを使用して別のプロセスにデータを送信するのに比べて少し労力が必要になります。

あなたのPHPスクリプトはApacheの外で起動する必要があり、入力データを読み込むために指定されたポートを継続的にリッスンする無限ループが必要になります。 following postは、私があなたが信じていることを概説しています。

EDIT

あなたは、このようなRedisのようなメモリデータストアで使用できるWebページに結果を表示するために。 PHPサーバアプリケーションは、redisでデータ構造を更新すると、Webページonloadはredisから最新の値を引き出し、画面に表示することができますが、ページの更新が必要になります。

サーバーのポストバックなしで受信したデータを直ちに更新する必要がある場合は、JavaScriptが必要です。ユーザーがページを読み込むと、WebSocketサーバーとのWebSocket接続が初期化されます(一般的に、これを実装するにはnode.jsとsocket.ioが使用されますが、WebSocketサーバーはこのテクノロジをサポートするものとしてコード化できます)。 websocketサーバーは、更新されると、接続されたすべてのクライアントに新しい値を送信するredisチャネルにサブスクライブされます。私は、あなたの要件が何であるかに応じて、これも赤字なくして行うことができると思います。 websocketサーバー用のプログラムは、別のスレッドを使用してC++プログラムから情報を受け取るサーバーでもかまいません。データがC++プログラムから来たら、websocket経由で接続しているクライアントに直接送ることができます。

+0

私はあなたがApacheの外でPHPスクリプトを使用することを意味します。どのように私はWebページ上の結果を視覚化することができますか? – Podarce

+0

@Podarce updated answer – commanderZiltoid

1

ホイールを改造しないでください。ウェブソケットを使用してください。この非同期通信を行うように設計されており、JSONを上手く送信できます。

C++とPHP用のライブラリがありますが、これはかなり簡単であるはずです。

+0

提案していただきありがとうございます。ヘッダーのみでない限り、外部ライブラリを読み込むことはできません。たぶん私はWebSocketのための自分のコードを書こうとすることができます、あなたはそれが実行可能だと思いますか? – Podarce

+0

いいえ、存在しないWebソケットはJSONオブジェクトをソケット上で前後にスローします。唯一の問題は、オブジェクトがバッファ内でいつ完了するかわからないため、長さを最初に送信し、次にJSONオブジェクトを送信しなければならないということです。次に、長さを読み取り、 JSON.parse()を実行し、次のメッセージのために残したものをそのまま残します。 – UserOneFourTwo

関連する問題