ユーザ用ツール

サイト用ツール


alworker:javascriptからipcをコールする

差分

この文書の現在のバージョンと選択したバージョンの差分を表示します。

この比較画面にリンクする

alworker:javascriptからipcをコールする [2014/11/20 12:51] (現在)
ライン 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 · 最終更新: 2014/11/20 12:51 by admin