前書き
fortran66 のブログさんの所に Fortran で書いた Web サーバーがあるので、これを借りて Fortran で出力した WebAssembly プログラムを、Fortran で書いた WEB サーバーで動かすことにします。
【メモ帳】ZMQ Fortran OO HTTP server
以下、多少問題がありますが、一応なんとか動かせました。
Fortran Web Server の準備
ZMQ のインストール
ZMQ というネットワーク・ライブラリを用意する必要があります。以下のページを参考にしました。
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 での計算が実行されます。
ブラウザ出力
コンソール出力
pc@VM10:~$ ./a.out
ZMQ http server:: http://localhost:8080
Received:: kEg
Received:: kEh
Received:: kEi
ただ、時々 WebAssembly の解釈をしくじってうまく動かないことがあります。その時は、Python サーバーを起動して、何かのページを表示させると、その終了後に問題が解決します。Fortran サーバープログラムでは、何らかの初期化か終了処理がされてない可能性があります。今後の課題といたします。
Python サーバー
python -m SimpleHTTPServer 8080