###### tags: `地圖產生器` # How 地圖產生器 show map creation progress? 2023.06.09 by [happyman](mailto:happyman.eric@gmail.com) 最後更新 2023.06.16 地圖產生器: https://twmap.happyman.idv.tw/ ## History 當 server 出圖的時候,需要讓 web client 知道出圖狀態。最早是用 php 的 system() 將 stdout 導向前端頁面。但是長時間跑的 script 前端可能中斷,為了解決這問題,於 2013年改為 Server push 採用 comet 的 ajax 實作 [Ape](https://github.com/APE-Project/APE_Server) ,將執行的過程 "push" 到 web client。中間又混了10年,終於2023年6月,改為 websocket 實作。 ## Current 1. protocol 自訂的 protocol很簡單,client收到訊息之後解析字串,然後輸出訊息、更新progress bar等,訊息不會影響後端,所以沒有考慮 authentication。 解析訊息參考: https://github.com/happyman/twmap/blob/v3.03_v4.34/twmap_gen/js/twmap.js#L124。 1. 前端 Web: 使用會斷線自動重連的 [reconnect websocket](https://github.com/joewalnes/reconnecting-websocket)。channel 由 mapform page 執行時產生,所以每次都會不一樣。所以其他人要猜到 channel 也不容易。 前端就走 wss, 而且可以透過 [cloudflare](https://developers.cloudflare.com/support/network/using-cloudflare-with-websockets/) cdn. 1. 後端 worker: 因為 websocket 的 tool 已經方便到了極點,所以實作起來一點都不費力。常用 socat,那用 websocat ([**web**socket**socat**](https://github.com/vi/websocat)) 就對了。 由 server 發訊息就這麼簡單。 https://github.com/happyman/twmap/blob/v3.03_v4.34/twmap_gen/lib/STB.inc.php#L622 怕字串被 shell 吃掉,所以 base64 encode 一下。 因為透過 websocket 可以躲在 cdn 後面,但 worker 到 client 要透過外部有點多餘,所以在 cmd_make2.php 加上 shortcut。於呼叫 worker 時候指定如 ws://homevm:9002/twmap_ 參考: https://github.com/happyman/twmap/blob/v3.03_v4.34/twmap_gen/cmd_make2.php#L344 既然每次都是連往同一個 ws,所以利用 websocat 的 reuse socket 功能,先把 redirector 跑起來,之後就只要 nc 即可,更快速。避免程式中斷後,daemon 還留在背景,記得要 register shutdown function 跟 catch ctrl-c 等中斷,把 daemon kill 掉。https://github.com/happyman/twmap/commit/de899ac5c4ffe69dbb9346aa5fd79bed93cf0501 1. Websocket Server: 使用 wsbroad ([**w**eb**s**ocket**broad**cast](https://github.com/vi/wsbroad/)) 連上同一個 url 的為同一個 channel,所以以上都連上相同的 channel, /twmap_[channel], twmap_ 是用來做 prefix,可讓前端(haproxy)做識別,萬一同一個 server ip 要送到不同的 websocket server。目前的 domain 是 ws.happyman.idv.tw 藏在 cloudflare 後面。 ``` # haproxy.cfg frontend tile acl hdr_connection_upgrade hdr(Connection) -i upgrade acl hdr_upgrade_websocket hdr(Upgrade) -i websocket acl is_wsbroad path_beg -i /twmap use_backend ws_wsbroad if hdr_connection_upgrade hdr_upgrade_websocket is_wsbroad { ssl_fc } backend ws_wsbroad mode http timeout tunnel 3600s server wsbroad 127.0.0.1:9002 ``` ## Showcast {%youtube _WyosbwPZVE %} https://youtu.be/_WyosbwPZVE ## 其他出圖方式? 其實可以不需要網頁介面,於自己的pc上出圖。 https://github.com/happyman/docker-twmap-cli https://hub.docker.com/repository/docker/happyman/docker-twmap-cli/general ## Feedback 歡迎留下你寶貴的建議。 https://www.facebook.com/twmapgen/ ### history 2023.6.9 initial 2023.6.16 add reuse socket implementation and cloudflare 說明