Bunのページ https://bun.sh/ へ行くと、まず「高速な JavaScriptランタイム・パッケージマネージャー・バンドラ―」などと書かれており、次のようなベンチマークが目を引きます。
速いですね。WebSocket好きは黙っていられない速度です。まぁ、他のHTTPサーバーやsqlitのベンチも驚くべきものですが、今回は早速WebSocket使ってBunで書いてみました。
とりあえず説明は Wiki に任せます。こんな感じ。
Bunとは、プログラミング言語Zigを用いてゼロから構築されたJavaScriptランタイム、パッケージマネージャー、テストランナービルダーである[3]。Jarred SumnerによってNode.jsの完全互換として設計された。Node.jsやDenoはJavaScriptエンジンとしてV8を利用しているが、BunはJavaScriptCoreを採用している
バンドル、縮小化、サーバーサイドレンダリング(SvelteKit、Nuxt.js、Vite) がサポートされている。
ランタイムではForeign function interface (FFI)、SQLite3、TLS 1.3、DNS解決がサポートされている。 また、ファイル編集、HTTPサーバー、WebSocket、ハッシュ関数などの一般的なツールも提供されている[5]
BunのWebsocketドキュメントは下記にあります
Bun>Websocket
このチャートの動作サンプル
動作サンプルURL
https://ccchart.com/bun/ws-8116.html
動画
環境と準備
環境:Ubuntu 20.04.6 LTS
- Bunインストール
- WebSocketサーバー側を作る
- ccchartで受信する
Bunインストール
インストールガイド
https://bun.sh/docs/installation
ここでは、Ubuntuで試しますが、上記Installationには、macOS and Linux、WindowsやDockerの各ケースが書かれています。
.
├─server/
│ └─ws-8116.js
├─html/
│ ├─ws-8116.html
│ └─js/ccchart.js
≈
//TSL/wss用のパス
(/etc/letsencrypt/live/example.com/privkey.pem など)
├─/<PathTo>/privkey.pem
└─/<PathTo>/fullchain.pem
sudo apt install unzip
curl -fsSL https://bun.sh/install | bash
WebSocketサーバー側を作る
WebSocketは、常時接続後chatなどのようにメッセージのやり取りをするものが多いですが、ここでは、コネクションが成立した「open」後にブロードキャスト関数broadCastを起動して、データを配信するだけの放送型の使い方をしています。
const server = Bun.serve({
hostname:'<IPやドメイン名>',
port: 8116, //ポートは開いて無ければ開けておく
fetch(req, server) {
// upgrade the request to a WebSocket
console.log('upgrade')
if (server.upgrade(req)) {
return; // do not return a Response
}
return new Response("Upgrade failed :(", { status: 500 });
},
websocket: {
open(ws) {
// ブロードキャスト
broadCast(ws)
},
message(ws, message) {},
close(ws) {},
},
tls: {
key: Bun.file('/<PathTo>/privkey.pem'),
cert: Bun.file('/<PathTo>/fullchain.pem'),
}
});
// info
console.log(`Listening on ${server.hostname}:${server.port}`);
// 全クライアントへ200ms毎にブロードキャストする
function broadCast(ws){
const INTERVAL=200
let tid = setInterval (function(){
let dataAry = mkData();
ws.send(JSON.stringify(dataAry));
}, INTERVAL);
}
// データ作成
// チャート用の時分秒と2つのランダムデータをつくる
function mkData(){
const data = [
["年度"],
["s2"],
["s3"]
];
let now = new Date();
let H = now.getHours();
let M = now.getMinutes();
let S = now.getSeconds();
H = (H < 10)?'0'+H:H;
M = (M < 10)?'0'+M:M;
S = (S < 10)?'0'+S:S;
data[0]=H +':' + M +':' + S;
data[1]=18 + Math.floor(Math.random(10) * 75 );
data[2]=32 + Math.floor(Math.random(10) * 18);
return data;
}
サーバーを起動する
sudo bun run /server/ws-8116.js
bunの場所がわからなければwhich bunなどで探してね
ccchartで受信する
ここでは、WebSocketサーバーから200ms毎に配信されてくるデータをccchartで受信し、チャート描画しています。もちろん、他のチャートライブラリでの描画も可能です。
ccchartは、私が昔作ったチャートライブラリでWebSocketの受信が手軽にできます。
https://ccchart.com/
<!DOCTYPE html>
<html lang="ja">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<head>
<title>ccchart bun test</title>
</head>
<body>
<!-- ccchart -->
<!--script src="https://ccchart.com/js/ccchart.js" charset="utf-8"></script-->
<script src="./js/ccchart.js" charset="utf-8"></script>
<div class="chart">
<canvas
id="hoge1"
class="-ccchart"
title="bg: '#eee'"
style="width:100%;height:100%;display: block; background-color: rgb(238, 238, 238);">
</canvas>
</div>
<script>
/* =============================================
* チャート設定
*/
let chartCfg1 = {
"config": {
"title" : "BunでWebSocket",
"subTitle" : "BunでWebSocketサーバーを作ってみた",
"type": "line",
"minY": 0,
"maxY": 100,
"lineWidth": 1,
"xScaleSkip": 5,
"colorSet" : ["red","orange"],
"useMarker": "maru",
"xLines": [
{"val":66,"color":"rgba(0,0,0,0.7)"}
],
"bg": "#fff",
"textColors": {
"title":"#777",
"subTitle":"#777",
"x":"#999",
"y":"#999",
"hanrei":"#777",
"unit":"#777",
"memo":"#666"
},
"shadows": {
"hanrei" : ['#aaa', 5, 5, 5],
"xline": ['#888', 7, 7, 5],
"line": ['#666', 5, 5, 5],
"bar": ['#bbb', 5, 5, 5],
"stacked": ['#bbb', 5, -5, 5],
"stackedarea": ['#666', 5, 5, 5],
"bezi": ['#666', 5, 5, 5],
"bezi2": ['#666', 5, 5, 5]
},
"markerWidth" : 12,
"lineWidth" : 2,
"bg": "#eee"
},
"data": [
["時間"],
["データ1"],
["データ2"]
]
};
ccchart
.init('hoge1', chartCfg1)
.ws('wss://ccchart.com:8116') //←ここは御自身のアドレス:ポート
.on('message', ccchart.wscase.oneColAtATime);
//oneColAtATimeは、WebSocketの受信パターン関数
// 一度に1列ずつ [["2013"],[435],[600]] といった配列で届く場合用
</script>
</body>
</html>
自己紹介
ここのCTOやってます
霊園ガイドサイト
https://reien.top/
Github https://github.com/toshirot
Qiita https://qiita.com/toshirot
ccchat https://ccchart.com/ javascript チャートライブラリ
霊園ガイド https://reien.top/ 霊園マッチングサイト
国会図書館 高橋著作 https://ndlonline.ndl.go.jp/#!/search?searchCode=SIMPLE&lang=jp&keyword=%E9%AB%98%E6%A9%8B%E7%99%BB%E5%8F%B2%E6%9C%97