0
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

posted at

updated at

Fortran サーバーで WebAssembly

前書き

fortran66 のブログさんの所に Fortran で書いた Web サーバーがあるので、これを借りて Fortran で出力した WebAssembly プログラムを、Fortran で書いた WEB サーバーで動かすことにします。
【メモ帳】ZMQ Fortran OO HTTP server

Fortran で WebAssembly 令和元年版

以下、多少問題がありますが、一応なんとか動かせました。

Fortran Web Server の準備

ZMQ のインストール

ZMQ というネットワーク・ライブラリを用意する必要があります。以下のページを参考にしました。

【メモ帳】WSL Ubuntu18.04 再構築

wget https://github.com/zeromq/libzmq/releases/download/v4.3.1/zeromq-4.3.1.tar.gz

tar zxvf zeromq-4.3.1.tar.gz
cd zeromq-4.3.1
./configure
make -j 8
sudo make install

Fortran http server 修正

ZMQ の Fortran binding も必要になります。f66blog/testZMQ から借りてきます。

元のサーバープログラムには、HTML ファイルの中身が直書きされているので、外部ファイル(HTTP.html)から読めるように直しました。この時プログラム中で、読み込んだ HTML ファイルの各行末に LF 文字を付け加える必要がありました。また flang ではコンパイルできなかったので、gfortran を用いました。

sudo apt install gfortran

wget https://raw.githubusercontent.com/f66blog/testZMQ/master/F08_ZMQ.f90

gfortran F08_ZMQ.f90 HTTPserver.f90 -lzmq
program test
    use, intrinsic :: iso_c_binding
    use f08_zmq
    implicit none
    integer :: id_size, iraw_size, ilen
    character(1025), target :: id, raw
    type(context_t), allocatable :: ctx
    type(socket_t) , allocatable :: socket
    character(len = 1024) :: buff
    character(len = :), allocatable :: http_response
    character(*), parameter :: fn = 'HTTP.html'

! READ HTTP file  ; add LF
    http_response = 'HTTP/1.0 200 OK'          // achar(10) // &
                    'Content-Type: text/html'  // achar(10) // achar(10)
    open(10, file = fn)
    do
        read(10, '(a)', end = 99) buff
        http_response = http_response // trim(buff) // achar(10)
    end do
 99 continue

! ZMQ HTTP server
    allocate(ctx, socket)
    call ctx%new()
    call socket%new(ctx, ZMQ_STREAM)
    call socket%bind('tcp://*:8080')
    print *, 'ZMQ http server:: http://localhost:8080'
    do
        call socket%recv(id, len(id), 0, id_size)
        print *, 'Received::', id(:id_size)
        do
            call socket%recv(raw, len(raw),  0, iraw_size)
            if (iraw_size <= 1024) exit
        end do
        call socket%send(id, id_size, ZMQ_SNDMORE, ilen)
        call socket%send(http_response, len(http_response), 0, ilen)
        call socket%send(id, id_size, ZMQ_SNDMORE, ilen)
        call socket%send('', 0, 0, ilen)
    end do
    deallocate(socket)
    deallocate(ctx)
end program test

WebAssembly 用 HTML ファイル

よく理解できない理由で、前に作った HTML ファイルでは動作しなかったので修正しました。

参考記事:
TypeError: Incorrect response MIME type. Expected 'application/wasm'

richlum commented on 19 Dec 2018
similar issue using 'web server for chrome' on linux. Adapted timmyjose solution while trying to follow along https://developer.mozilla.org/en-US/docs/WebAssembly/Text_format_to_wasm

<!-- public/index.html -->
<!DOCTYPE html>
<html lang="en">
  <body>
    <script>
      fetch('./pai.wasm').then(response => response.arrayBuffer()
      ).then(bytes => {
        return WebAssembly.instantiate(bytes, {})
      }).then( r => {
        const ex = r.instance.exports
        const n = 64
        const result = ex.pai(n + 1)
        const theory = ex.pai2()
        console.log(result)
        console.log(theory)
        document.querySelector("#n_div" ).innerHTML = n
        document.querySelector("#result").innerHTML = result
        document.querySelector("#theory").innerHTML = theory
      })
    </script>

    Division of Interval
    <div id="n_div"> </div>
    Result
    <div id="result"></div>
    Theoretical value
    <div id="theory"></div>

  </body>
</html>

実行

./a.out でサーバーが起動し、ブラウザで localhost:8080 と打てば、別記事で生成した WebAssembly での計算が実行されます。

ブラウザ出力

zmqWebAssembly.png

コンソール出力

pc@VM10:~$ ./a.out
 ZMQ http server:: http://localhost:8080
 Received:: kEg
 Received:: kEh
 Received:: kEi

ただ、時々 WebAssembly の解釈をしくじってうまく動かないことがあります。その時は、Python サーバーを起動して、何かのページを表示させると、その終了後に問題が解決します。Fortran サーバープログラムでは、何らかの初期化か終了処理がされてない可能性があります。今後の課題といたします。

Fortran で WebAssembly 令和元年版

Python サーバー

python -m SimpleHTTPServer 8080
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
0
Help us understand the problem. What are the problem?