Fortran サーバーで WebAssembly

# 前書き
fortran66 のブログさんの所に Fortran で書いた Web サーバーがあるので、これを借りて Fortran で出力した WebAssembly プログラムを、Fortran で書いた WEB サーバーで動かすことにします。
[【メモ帳】ZMQ Fortran OO HTTP server](http://fortran66.hatenablog.com/entry/2019/06/15/003938)

[Fortran で WebAssembly 令和元年版](https://qiita.com/cure_honey/items/dbc06a088d2a7f86fbbd)

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

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

[【メモ帳】WSL Ubuntu18.04 再構築](http://fortran66.hatenablog.com/?page=1561283292)

```
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](https://github.com/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
```

```fortran
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'](https://github.com/mdn/webassembly-examples/issues/5)

> 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

```HTML
<!-- 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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44522/d33194c8-bb93-71d0-3084-7e941d662dd2.png)

### コンソール出力
```
pc@VM10:~$ ./a.out
 ZMQ http server:: http://localhost:8080
 Received:: kEg
 Received:: kEh
 Received:: kEi
```


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

[Fortran で WebAssembly 令和元年版](https://qiita.com/cure_honey/items/dbc06a088d2a7f86fbbd)

Python サーバー

```python
python -m SimpleHTTPServer 8080
```