それらが改行で区切られた単純なコマンドである場合、独自のクライアントをロールするのは非常に簡単です。
編集: HTTP は、長期間接続を開いたままにしておくための最適なプロトコルではなく、タイムアウトの問題が発生する可能性があります。以下のコードはテストされていませんが、良い出発点になるはずです。
EDIT 2:コメントで指摘されているように、ここではスレッド プールが必要または有用である場合とそうでない場合があります。スレッドを使用しても、魔法のように処理が速くなったり、処理できるリクエストの量が増えたりするわけではないことに注意してください。スレッド プールを使用する利点は、前のコマンドがまだ実行されている間に、クライアントが新しいコマンドをすぐに受信できるようになることです。コマンドの処理に I/O タスクが必要な場合 (別のサーバーへの呼び出しなど) は重要かもしれませんが、あなたの状況ではやり過ぎかもしれません。
ExecutorService svc = Executors.newCachedThreadPool();
URLConnection c =
new URL("http://192.168.1.122/push/out.php?nduid=1").openConnection();
c.setReadTimeout(30 * 60 * 1000); // Set the read timeout to 30 minutes
c.connect();
InputStream is = c.getInputStream();
BufferedReader r = new BufferedReader(new InputStreamReader(is, "UTF-8"));
String cmd = null;
while ((cmd = r.readLine()) != null) {
svc.execute(new Runnable() {
public void run() {
processCmd(cmd); // work happens here in a different thread.
}
});
}
is.close();
ここで重要なのは、ソケットから返された入力ストリームが、基礎となる TCP 接続が開いている限り開いたままになることです。クライアントはストリームからの読み取りを続けることができ、readLine
呼び出しは新しいデータが到着するまで必要に応じてブロックされます。null が返された場合readLine
は、基になる入力ストリームがファイルの終わりに達したことを意味し、サーバーがソケットを閉じたことを意味します。
完全なデータ行を取得したら、それをスレッド プールに送信して、別のスレッドで解析および実行することができます。このように作業を分割すると、1 行のテキストからコマンドを解析して実行することに集中できます。これは、任意に大量のデータ ストリームを処理しようとするよりもはるかに扱いやすいものです。