websocketj:Webブラウザからサーバープログラムを操作する

0 - Linux標準ターミナルの入出力に退屈していませんか?

1 - vmstatコマンドの出力が直感的でない?出力を視覚化する方法を考えたことはありますか?

2 - ブラウザからWindowsのcmdを操作してみましたか?

websocketjはこれらの問題を全て解決し、ブラウザ経由でいつでもどこでも任意のプラットフォーム上のアプリケーションにアクセスできるようにします。

  • websocketjとは?
  • websocketjの使い方
  • websocketjの動作原理
  • ブラウザでWindowsのcmdを遠隔操作
  • ブラウザでLinuxのvmstat出力を視覚化
  • 今後の改善予定
  • 巨人の肩に乗って
  • ソースコードのコンパイル方法

GitHubでwebsocketjをForkする

websocketjとは?

名前の通り、websocketjはWebSocketに関連しています。簡単に言うと、サーバープログラムの標準入出力(STDINとSTDOUT)を、WebSocketプロトコルをサポートするリモートブラウザにリダイレクトします。

プログラムの標準出力はメッセージとしてリモートブラウザに送信され、リモートブラウザからのデータはプログラムの標準入力として扱われます。サーバープログラムがJava、Python、C、C#、Ruby、Swift、Goなど、どんな言語で書かれていても、STDINとSTDOUTをサポートしていれば、websocketjは問題なく動作します。

websocketjはWebSocketサーバーとしてクライアント接続を受け付けるだけでなく、静的なWebサーバーとしても機能します。HTML、JS、CSS、画像などの静的なリソースリクエストを処理できます。Javaで実装されており、コード構造はシンプルで、他のコンポーネントに依存せず、TomcatやNginxなども必要ありません。単独で完全に動作します。とても強力です。

websocketjの使い方

では、実際にどのように使用するのでしょうか?使い方は非常に簡単です。以下の手順に従ってください。

  • Step1: サーバープログラムを開発します。言語は問いませんが、標準入出力(STDINとSTDOUT)をサポートしている必要があります。
  • Step2: フロントエンドプログラム(HTML、CSS、JSなど)を開発します。WebSocketクライアント接続コードを作成し、サーバーからのデータを受信します。必要に応じて、ユーザーの入力をサーバーに送信する機能も含めます。
  • Step3: フロントエンドプログラムファイル(HTMLなど)をサーバー(例:Linux)の適切なディレクトリ(例:'/usr/local/websocketj/html')に配置します。他のプラットフォームでも同様です。
  • Step4: websocketjを起動し、起動パラメータを指定します。例:'websocketj --wsport=8081 --ssport=8082 --staticDir=/usr/local/websocketj/html/ yourprogram args...'
  • Step5: ブラウザを開き、アドレスバーに 'http://ip:8082/' と入力します。デフォルトのホームページが表示されれば、websocketjの起動成功です。

起動パラメータの説明:

--wsport: WebSocketサーバーのポート番号。

--ssport: 静的なWebサーバーのポート番号。

--staticDir: 静的なリソース(HTML、CSS、JSなど)を格納するディレクトリ。Tomcatのwebappsディレクトリに相当します。--ssportポート経由でアクセスできます。

Yourprogram args: 作成したSTDINとSTDOUTをサポートするサーバープログラムと、その引数です。通常のコマンドライン起動と同様です。

注意:websocketjが正常に起動すると、8082ポート(例:http://192.168.3.73:8082/)にアクセスすることで、デフォルトのホームページを確認できます。

websocketjの動作原理

websocketjは、ブラウザとアプリケーションの間の橋渡し役のようなものです。プログラムのInputStreamとOutputStreamをフックし、WebSocket技術を使用してこれらのストリームをリモートのWebブラウザに再ルーティングします。

構造は非常にシンプルで、一目で理解できます。簡単な例として、サーバー側でbashシェルを使ってシステム時刻を定期的に出力するスクリプトを作成し、フロントエンドでHTMLファイルを作成し、JavaScriptでWebSocketを使用してシェルスクリプトの出力をリアルタイムに受信してブラウザページに表示する方法を示します。

bashシェル(ファイル名: show_time):

#! /bin/bash<br>
while [ true ]
do
echo "time from linux server:"$(date +%X)
sleep 1 
done
exit 0

HTML(ファイル名: show_time.html):

<script><br>    // 補助関数: メッセージを画面に表示
    function ログ出力(msg) {
        document.getElementById('msg').textContent = msg;
    }

    function 出力表示(output) {
        document.getElementById('output').textContent = output;
    }
 
     // コールバックを設定してWebSocketを構築
     var host = "ws://192.168.3.246:8081/";
     var ws = new WebSocket(host);
     ws.onopen = function() {
         ログ出力("WebSocketサーバーに接続しました: => " + host);
     };
     ws.onclose = function() {
         ログ出力('切断されました');
     };
     ws.onmessage = function(event) {
         出力表示(event.data);
     };
</script>    

show_time.htmlファイルをLinuxの任意のディレクトリに配置し、websocketjを起動します:websocketj --wsport=8081 --ssport=8082 --staticDir=/usr/local/websocketj/html ./show_time。そして、ブラウザで 'http://192.168.3.246:8082/show_time.html' にアクセスすると、Linuxの時刻がリアルタイムにページに表示されます。このテキストはbashシェルスクリプトのSTDOUTから取得されています。

ブラウザでWindowsのcmdを操作

ここでは、Windows 10にインストールされたgit cmdを例に、ブラウザからgit cmdクライアントを操作する方法を紹介します。既存のgit cmdプログラムを直接使用するため、サーバープログラムを作成する必要はありません。出力を受信し、入力をシミュレートするためのフロントエンドHTMLページだけを作成します。HTML(git_cmd.html)ページはここでは省略します。このgit_cmd.htmlファイルをWindowsの任意のディレクトリ(例:E:\codes\git\websocketj\html)に配置し、websocketjを起動します:websocketj --wsport=8081 --ssport=8082 --staticDir=E:\codes\git\websocketj\html "C:\Program Files\Git\git-cmd.exe"。そして、ブラウザで 'http://192.168.3.74:8082/git_cmd.html' にアクセスし、gitコマンドを入力して出力を確認します。

ブラウザでLinuxのvmstat出力を視覚化

Linuxには、CPUやネットワークなどのシステムリソースの使用状況を監視するコマンドがあります。'vmstat 1' コマンドを実行すると、コンソール端末に現在のシステム状態が1秒ごとに出力されます。

ここでは、websocketjを使用して上記の出力をブラウザにリダイレクトし、ブラウザ上でJSライブラリを使用してこれらのデータを視覚化します。既存のLinuxコマンド(vmstat 1)を使用するため、サーバープログラムを作成する必要はなく、表示用のフロントエンドHTMLファイルのみが必要です。フロントエンドでは、このような監視データの視覚化に特化したサードパーティのJSライブラリ(http://smoothiecharts.org/)を使用しました。詳細なコードはここでは省略しますが、興味があれば公式サイトをご覧ください。以下が最終的な効果図です。

今後の改善予定

現在考えられる改善点は以下の通りです。

(1)フロントエンドから任意のサーバープログラムを動的に起動できるようにする。現在は起動時にパラメータとして1つのプログラムしか指定できず、すべてのフロントエンド接続がそのプログラムの入出力を共有します。改善後は、フロントエンドから起動するプログラムを指定できるようになり、異なるフロントエンドが異なる入出力に関連付けられます。

(2)WebSocket接続時に認証を必要とする。現在はすべての接続がプログラムの入出力にアクセスできますが、改善後は認証された接続のみがアクセス可能になります。

(3)皆様の情熱とアイデアをお待ちしています。

PRやIssueを歓迎します。GitHubでwebsocketjをForkしてください。

巨人の肩に乗って

これまで、このツールは非常にシンプルだと述べてきましたが、実際はそうではありません。WebSocket部分では、サードパーティのオープンソースWebSocketライブラリを利用しています。詳細なソースコードはこちら(https://github.com/TooTallNate/Java-WebSocket)を参照してください。このライブラリを使用すると、WebSocketサーバーやクライアントを非常に簡単に作成できます。

import java.net.InetSocketAddress;
import org.java_websocket.WebSocket;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;

public class シンプルサーバー extends WebSocketServer {
    public シンプルサーバー(InetSocketAddress address) {
        super(address);
    }
 
     @Override
     public void onOpen(WebSocket conn, ClientHandshake handshake) {
         conn.send("サーバーへようこそ!"); // このメソッドは新しいクライアントにメッセージを送信します
         broadcast( "新しい接続: " + handshake.getResourceDescriptor() ); // このメソッドは接続している全てのクライアントにメッセージを送信します
         System.out.println("新しい接続: " + conn.getRemoteSocketAddress());
     }
     @Override
     public void onClose(WebSocket conn, int code, String reason, boolean remote) {
         System.out.println("接続が閉じられました: " + conn.getRemoteSocketAddress() + " 終了コード: " + code + " 追加情報: " + reason);
     }
     @Override
     public void onMessage(WebSocket conn, String message) {
         System.out.println("メッセージを受信: " + conn.getRemoteSocketAddress() + ": " + message);
     }
     @Override
     public void onMessage( WebSocket conn, ByteBuffer message ) {
         System.out.println("ByteBufferを受信: " + conn.getRemoteSocketAddress());
     }
     @Override
     public void onError(WebSocket conn, Exception ex) {
         System.err.println("接続でエラーが発生しました: " + conn.getRemoteSocketAddress() + ":" + ex);
     }
     @Override
     public void onStart() {
         System.out.println("サーバーが正常に起動しました");
     }
     public static void main(String[] args) {
         String host = "localhost";
         int port = 8887;
 
         WebSocketServer server = new シンプルサーバー(new InetSocketAddress(host, port));
         server.run();
     }
 }

コードスタイルはJavaScriptに似ており、非常に使いやすいです。サーバー機能に加えて、このライブラリを使用してWebSocketクライアントを迅速に作成することもでき、ブラウザをシミュレートしてWebSocket接続を行うことができます。また、細かい点に気づかれた方もいるかもしれませんが、websocketjはGo言語版の別のツールであるwebsocketd(https://github.com/joewalnes/websocketd/)を模倣しています。websocketdの方が機能が豊富ですが、私はその機能を参考にしただけで、実装については参照していません。WebSocket部分についても、websocketdはGo言語版のサードパーティオープンソースライブラリを利用しています。

ソースコードのコンパイル方法

git cloneコマンドでソースコードをローカルディレクトリにクローンした後、

Windows:

Eclipseを使用してMavenプロジェクトとしてインポートします。

Linux:

Linuxでのコンパイルと実行はやや複雑で、-Djava.ext.dirs=パラメータを追加してJARファイルを参照する必要があります。また、コンパイルにはルートディレクトリのsources.buildファイルを使用します。このファイルには、さまざまなソースファイルのリストが含まれています。

Linuxでのコンパイル:javac -Djava.ext.dirs=../libs/ @sources.build

Linuxでの実行:java -Djava.ext.dirs=../libs/ -classpath ./src/main/java/ com.zhzhi.websocketj.App --wsport=8081 --ssport=8082 --staticDir=../html/ vmstat 1

タグ: websocket Java コマンドライン 標準入出力 リモートアクセス

7月22日 18:57 投稿