非同期通信と同期通信

Ajaxは(Asynchronous JavasScript + XML)という名前の通り、XMLHttpRequestというクラスを利用しAsynchronous(非同期通信)を実現できるという点が取り上げられ流行しています。もちろんCurlでも非同期通信を実現できるので、実装方法を紹介していきたいと思います。

同期通信

以下に、サーバへアクセスし、応答結果をアプレット上に表示するというサンプルコードを紹介していきます。

{curl 6.0 applet}

{let out:Frame = {Frame}} || 表示用
{value
    def remote-url = {url “http://www.curlap.com“}
    def http-file = {remote-url.instantiate-File} asa HttpFile
    {with-open-streams tis:HttpTextInputStream =
        {http-file.http-read-open} || 同期通信
      do
        let buf:StringBuf = {StringBuf}
        {tis.read-one-string buf = buf}
        {out.add {buf.to-String}}
    }
    out
}

サーバのURLからHttpFileオブジェクトを生成します。そのHttpFileオブジェクトのread-openメソッドを利用しサーバへリクエストします。サーバが返した結果(ここではHTML)をアプレットに表示しています。

非同期通信

非同期通信のサンプルコードも同様に結果をアプレットに表示します。非同期ではリクエストした結果を受け取った際に実行するためのコールバックプロシージャを用意します。以下のサンプルでは、callback-procプロシージャを用意し、非同期通信処理の終了後にこのプロシージャに結果を引数として渡して実行されるようにしています。

{curl 6.0 applet}

{let out:Frame = {Frame}}
{value
    let callback-proc:{proc-type {#Exception, #String}:void}
        = {proc {ex:#Exception, value:#String}:void
    {if-non-null ex then
        {output ex.message}
        {return}
    }
    {out.add value}
}

def remote-url = {url “http://www.curlap.com“}
def http-file = {remote-url.instantiate-File} asa HttpFile

let worker:AsyncWorker =
    {http-file.http-async-read-open
        {on e:AsyncFileOpenEvent do
            {if-non-null ex = e.exception then
                {callback-proc ex, null}
                {return}
             else
                {if-non-null tis = e.stream asa #TextInputStream then
                     let buf:StringBuf = {StringBuf}
                     set worker =
                          {tis.async-read-string
                              buf = buf,
                              {on e:AsyncStreamReadEvent do
                                  {callback-proc null, {buf.to-String}}
                                  {tis.close}
                              }
                          }
                }
            }
        }
    }

    out
}

HttpFileオブジェクトを生成するところまでは同期通信と同様ですが、非同期通信ではHttpFileオブジェクトのasyn-read-openメソッドを利用し、サーバにリクエストします。非同期通信の場合は結果を受け取るとAsyncFileOpenEventが発生し、このイベントのstreamゲッターから結果のストリームデータを取得することとなります。また、非同期処理は例外をキャッチできないため、例外もAsyncFileOpenEventのexceptionゲッターから取得します。さらにストリームデータを非同期に読み込むために、TextInputStreamにはasync-read-stringメソッドが用意されています。

コードサンプルのダウンロード

通信のコードサンプル