33.32.1 概観

specから引用するとJSONRPCは、"同一プロセス、ソケットやhttp、多くのさまざまなメッセージパッシング環境において使用可能という概念においてトランスポート非依存"です。

この非依存性をモデル化するために、jsonrpcライブラリーはリモートのJSONのエンドポイントへの接続の表現にjsonrpc-connectionクラスのオブジェクトを使用します(Emacsのオブジェクトシステムの詳細はEIEIO in EIEIOを参照)。これはオブジェクト指向の現代的な用語では“抽象的(abstract)”なクラス、すなわち有用な接続オブジェクトの実クラスは常にjsonrpc-connectionのサブクラスになります。それにも関わらず、jsonrpc-connectionクラスを中心に2つのAPIを個別に定義できます。

  1. JSONRPCアプリケーション構築用のAPI

    このシナリオでは野心的な新しいJSONRPCベースのアプリケーションが、エンドポイント間で取り交わされるJSONRPCメッセージのトランスポートを提供するjsonrpc-connectionの具体的なサブクラスを選択したものとする。

    アプリケーションはmake-instanceを用いてそのサブクラスのオブジェクトを作成する。リモートのエンドポイントとの接続を開始するために、アプリケーションはそのオブジェクトをjsonrpc-notifyjsonrpc-requestjsonrpc-async-requestのような関数に渡す。

    リモートで開始された接続(通常は非同期で到来)を処理するには、make-instanceによるインスタンス化においてEIEIOのキーワード引数:request-dispatcherおよび:notification-dispatcherを用いて初期化する必要がある。これらはいずれも接続オブジェクト、リモート呼び出しされるJSONRPCメッセージを命名するシンボル、JSONRPCのparamsオブジェクトという3つの引数をもつ。

    :request-dispatcherとして渡される関数はリモートのエンドポイントのリクエストを処理する役目をもち、ローカルのエンドポイント(この例では構築中のアプリケーション)からのリプライを期待する。この関数の内部ではローカルにリターン(通常のリターン)、あるいは非ローカルにリターン(エラーをthrow)できる。リクエストディスパッチャーからどちらでexitしたとしても、トランスポートを通じてリモートのエンドポイントにリプライが送信される。

    通常のリターンは成功レスポンスと判断される。リターン値はJSONとしてシリアライズ可能なLispオブジェクトでなければならない(JSON値の解析と生成を参照)。この結果はJSONRPCのresultオブジェクトとしてサーバーにフォワードされる。非ローカルなリターンは関数jsonrpc-errorを呼び出すことによって行われる。これによりエラーのレスポンスがサーバーに送信される。JSONRPCのerrorに付随する詳細には、jsonrpc-errorに渡されるものすべてが含まれる。他のタイプの予期せぬエラーからトリガーされた非局所的なリターンでも、( debug-on-errorをセットしていなければ)エラーレスポンスを送信して、この場合にはLispデバッガが呼び出される。エラーによるデバッガへのエンターを参照のこと。

    jsonrpcライブラリーを使用して、“準JSONRPC”として記述されたトランスポートプロトコルベースのアプリケーションを構築することは可能である。これらは似てはいるが、DAP (Debug Adapter Protocol)のようにJSONRPCと完全に同一ではない。これらのプロトコルはリクエスト、レスポンス、通知メッセージも定義しているがフォーマットはJSONRPCと完全に同一ではない。JSONRPCの内部表現とエンドポイントが受け入れる表現を変換するように、ジェネリック関数jsonrpc-convert-to-endpointおよびjsonrpc-convert-from-endpointをカスタマイズできる(ジェネリック関数を参照)。

  2. JSONRPCトランスポート構築用のAPI

    このシナリオでは基盤として異なるトランスポートストラテジーを実装するためにjsonrpc-connectionをサブクラス化する(サブクラス化する方法についての詳細はInheritanceを参照)。その後にアプリケーション構築インターフェースのユーザーは、( make-instance関数を使用して)その具象クラスのオブジェクトをインスタンス化して、そのストラテジーを使用してJSONRPCエンドポイントに接続できる。ビルトインのトランスポート実装については、プロセスベースのJSONRPC接続を参照のこと。

    このAPIには必須部分とオプション部分がある。

    JSONRPC接続(通知やリクエスト)を開始したりエンドポイントのリクエストへのリプライをユーザーに許すには、その新たなトランスポート実装がジェネリック関数jsonrpc-connection-sendを新たなサブクラス用に特化して実装しなければならない(ジェネリック関数を参照)。このジェネリック関数はjsonrpc-requestjsonrpc-notifyのようなプリミティブから自動的に呼び出される。この特化によって引数リストに記述されたメッセージが、基礎となる通信メカニズム(“wire”とも呼ばれる)を介して送信されて、新たなトランスポートがエンドポイントとの対話に使用することを保証する必要がある。この“wire”はネットワークソケット、シリアルインターフェイス、あるいはHTTP接続などかもしれない。

    同様に3種類のリモートコンタクト(リクエスト、通知、ローカルリクエストへの応答)を処理するために、トランスポート実装は“wire”上のJSONRPC(あるいは準JSONRPC)の作成に用いられるかもしれないJSONRPCメッセージに気づいたら、Elispから関数jsonrpc-connection-receiveが呼び出されるように計らわなければならない。

    最後にオプションとしてjsonrpc-connectionサブクラスはジェネリック関数jsonrpc-shutdownおよびjsonrpc-running-pにたいして、これらの概念をトランスポートに適用する場合には、これらのジェネリック関数を特化する必要がある。jsonrpc-shutdownの特化によって、wire上でのメッセージのlistenに用いたすべてのシステムリソース(プロセス、タイマー等)を確実にリリースすること、jsonrpc-running-pの特化によって、これらのリソースがまだアクティブなのか、(jsonrpc-shutdownやその他を通じて)すでにリリース済みかを伝えるように実装する必要がある。

This page has generated for branch:work/emacs-30_69b16e5c63840479270d32f58daea923fe725b90, commit:5e3f74b56ff47b5bcef2526c70f53f749bbd45f6 to check Japanese translation.