ユーザ用ツール

サイト用ツール


alworker:javascriptからipcをコールする
no way to compare when less than two revisions

差分

このページの2つのバージョン間の差分を表示します。


最新のリビジョン
alworker:javascriptからipcをコールする [2014/11/20 12:51] – 外部編集 127.0.0.1
行 1: 行 1:
 +====== AlWorker JavaScriptからIPCをコールする ======
 +
 +===== 背景 =====
 +
 +ブラウザでボタンが押された等のアクションを最終的にワーカーのIPCサービスが処理する場合、
 +伝達経路が長く使われるテクノロジーも多いので、ユーザープログラムが煩雑でデバッグもとても大変になります。
 +
 +{{:alworker:ipcimage1.png?nolink|}}
 +
 +そこで、2つのライブラリを使ってこの複雑さを隠蔽し、JavaScriptからWorkerのネイティブコードを呼び出すことができるようにしました。
 +
 +(利用イメージ)\\
 +{{:alworker:ipcimage2.png?nolink|}}
 +====== 使い方 ======
 +
 +===== 1. JavaScript "alone.js" ライブラリを読み込む =====
 +
 +htmlで、alone.jsが読み込まれる様に記述する。
 +<code html>
 +<script type="text/javascript" src="/PATH/TO/alone.js"></script>
 +</code>
 +
 +===== 2. AlControllerへIpcActionモジュールをincludeする =====
 +
 +cgiコントローラ内に次のように記述する。
 +<code ruby>
 +require "al_form"
 +require "al_worker_ipc"
 +
 +class AlController
 +  include AlWorker::IpcAction
 +</code>
 +
 +===== 3. JavaScriptからコールする =====
 +
 +<code javascript>
 +var ipc = new Alone.Ipc();
 +ipc.call( "NAME", { any_parameters: "any value" } );
 +</code>
 +
 +===== 注意 =====
 +AlWorker::IpcActionをincludeすることで、すべてのIPCをHTTP経由で外部に公開することになります。\\
 +セキュリティー上の理由などにより公開してはならないIPCがある場合、IPCソケットを公開用、非公開用に分離するか、module AlWorker::IpcActionを参考に、独自にメソッドを追加してください。
 +
 +
 +====== サンプル ======
 +
 +画面上のカウンタ(数字)を、ボタン操作によってアップダウンさせる。
 +
 +
 +===== 常駐サーバー =====
 +
 +あらかじめ、ウェブサーバーと同じマシンで実行しておく。
 +<file ruby count_server.rb>
 +require "al_worker_ipc"
 +
 +class CountServer < AlWorker
 +
 +  def initialize2()
 +    @ipc = Ipc.new()
 +    @ipc.chmod = 0666
 +    @ipc.run( self )
 +    set_value( "counter", 0 )
 +  end
 +
 +  # IPCコマンド counter を定義
 +  # (note)
 +  #  引数 param には、JavaScript側の callで指定したパラメータがそのまま渡ってくる。
 +  def ipc_counter( sock, param )
 +    counter = get_value( "counter" )
 +    case param["work"]
 +    when "up"
 +      counter += 1
 +    when "down"
 +      counter -= 1
 +    end
 +    set_value( "counter", counter )
 +    
 +    # 第4引数は、JavaScript側へそのまま返される。
 +    reply( sock, 200, "OK", {"counter"=>counter} )
 +  end
 +end
 +
 +server = CountServer.new( "count_server" )
 +server.parse_option()
 +server.daemon()
 +</file>
 +
 +
 +===== Alone cgiコントローラ =====
 +
 +<file ruby main.rb>
 +require "al_template"
 +require "al_form"
 +require "al_worker_ipc"
 +
 +class AlController
 +  include AlWorker::IpcAction
 +
 +  def initialize()
 +    @ipc = AlWorker::Ipc.open( "/tmp/count_server" )
 +  end
 +
 +  def action_index()
 +    @ipc.get_values()
 +    AlTemplate.run( "index.rhtml" )
 +  end
 +end
 +</file>
 +
 +
 +===== 画面テンプレートとJavaScript =====
 +
 +<file html index.rhtml>
 +<%= header_section %>
 +
 +<script type="text/javascript" src="/js/alone.js"></script>
 +<script type="text/javascript">
 +function count( work )
 +{
 +    var ipc = new Alone.Ipc();
 +
 +    // コールバックハンドラ。reply() の戻り値は、引数 data で渡される。
 +    ipc.success = function( data, status ) {
 +        var e = document.getElementById( "counter" );
 +        e.innerHTML = data.counter;
 +    }
 +
 +    // サーバーの ipc_counterメソッドをパラメータを付けて呼び出す。
 +    ipc.call( "counter", { work: work } );
 +}
 +</script>
 +<%= body_section %>
 +
 +カウンター <span id="counter"><%=h @ipc.values["counter"] %></span><br>
 +<input type="button" value="UP" onclick="count('up');">
 +<input type="button" value="DOWN" onclick="count('down');">
 +
 +<%= footer_section %>
 +</file>
 +
 +
 +
 +====== 個別機能 ======
 +
 +===== JavaScript ライブラリ =====
 +
 +IPCの戻り値
 +
 +success コールバックファンクションの第一パラメータで取得する方法と、ipc オブジェクトの、dataアトリビュートで取得する方法の2種類があります。\\
 +一般的にはコールバックファンクションを使う方が、やりやすいでしょう。
 +
 +AJAX
 +
 +jQueryが読み込まれていれば、AJAX接続にjQuery.ajax メソッドを使うようになります。\\
 +その場合、ipc.options が jQuery.ajax メソッド用の接続オプションとして使われますので、接続条件などを変更できます。\\
 +
 +
 +===== IPC接続先指定 =====
 +
 +IPCの接続先指定の方法は、4種類あります。
 +
 +1. コントローラのコンストラクタ等で @ipc オブジェクトを生成する。(推奨)
 +
 +<code ruby>
 +  def initialize()
 +    @ipc = AlWorker::Ipc.open( "/tmp/chat_server" )
 +</code>
 +
 +2. コントローラのコンストラクタ等で、@ipc_name でソケット名を与える。
 +
 +<code ruby>
 +  def initialize()
 +    @ipc_name = "/tmp/chat_server"
 +</code>
 +
 +3. httpリクエストに含める
 +
 +JavaScriptから
 +<code javascript>
 +ipc.call( "say", { message: "anything", ipc_name: "/tmp/chat_server" } );
 +</code>
 +
 +4. デフォルト値を使用
 +
 +何も指示しなければ、/tmp/al_worker をデフォルト値として使用し、IPC接続しようとする。
 +
 +
 +
 +====== プロトコル詳細 ======
 +
 +===== cgiリクエスト =====
 +
 +リクエストパラメータは、以下のようになります。
 +
 +  http://*.cgi?ctrl=xxx&action=ipc&ipc=IPCNAME&arg=ARGUMENT_encoded_by_json
 +
 +^パラメータ^意味^備考^
 +|ctrl|Aloneコントローラ|
 +|action|Aloneアクション|ipc固定|
 +|ipc|IPC名の指示|
 +|arg|引数 JSONエンコード|
 +
 +
 +===== 戻り値 =====
 +
 +以下の、2要素の配列が返ります。
 +
 +[IPCステータスコード, 戻り値をJSONエンコード]
 +
 +^index^内容^データタイプ^保存先^
 +|0|IPCステータスコード|String|ipc.status_code|
 +|1|戻り値|Hash(Object)|ipc.data|
  
alworker/javascriptからipcをコールする.txt · 最終更新: 2019/09/19 10:56 by hirohito