Disclaimer / 言い訳 ● I was planning to introduce some tips for WebSocket, but I find that these tips are not necessary in most situation. ● So I add some trivia about Bun and WebSocket. ○ Please relax and enjoy ● This slide is based on my personal study ○ Not official information ○ All errors are my mistakes. ● 当初 WebSocket にまつわる Tips をご紹 介する予定でしたが、その後ほとんどの場 面では不要なことがわかりました ● そのため、雑学を追加してお話しします ○ リラックスして、聞き流してください ● このスライドの内容は、個人的な実験結果 にもとづきます ○ 公式の見解ではありません ○ 誤りについてはすべて私個人の責任です My talk is mostly in English, some part is mixed with Japanese 英語メインで、一部日本語をミックスしてお話しします
What is Bun? https://bun.sh/ Bun is a fast all-in-one JavaScript runtime - using JavaScriptCore (JavaScript Engine) - implemented with Zig - support TypeScript - support some of npm modules - not socket.io - built-in modules - sqlite - tuned for some selected use cases (according to my impression) - For build tools - For dev server - Not for demon server process, but event hunder of serverless / edge servers https://bun.sh/ 「速い」「全部入り」の JavaScriptランタイム - JavaScriptCore をエンジンに使っている - Zigで開発されている - TypeScriptがそのまま動く - npmモジュールが(一部)使える - socket.io は未サポート - モジュールを内蔵(ビルトイン) - sqlite など - 特定のケースに対してチューニング(個人的 印象) - ビルドツール - 開発サーバ - 常駐サーバープロセスではなく、サーバーレ ス/エッジ環境のイベントハンドラ Bunとは?
Matrix of JavaScript Engine - Language - Runtime Implementation language of runtime → ↓ used JS Engine C C++ Rust Zig Go V8 Node.js Deno JavaScriptCore Bun SpiderMonky Chakra/ChakraCore (node-chakracore) QuickJS qjs
What is Bun? https://bun.sh/ Bun is a fast all-in-one JavaScript runtime - using JavaScriptCore (JavaScript Engine) - implemented with Zig - support TypeScript - support some of npm modules - not socket.io yet - built-in modules - sqlite - tuned for some selected use cases (according to my impression) - For build tools - For dev server - Not for demon server process, but event handler of serverless / edge servers https://bun.sh/ 「速い」「全部入り」の JavaScriptランタイム - JavaScriptCore をエンジンに使っている - Zigで開発されている - TypeScriptがそのまま動く - npmモジュールが(一部)使える - socket.io は未サポート - モジュールを内蔵(ビルトイン) - sqlite など - 特定のケースに対してチューニング(個人的 印象) - ビルドツール - 開発サーバ - 常駐サーバープロセスではなく、サーバーレ ス/エッジ環境のイベントハンドラ Bunとは?
Trivia 1: ws module for Bun / Bun と wsモジュール ● It seems that Bun supports "ws" module of npm. ● Actually, npm module is not used. ○ able to use "ws" without install. ○ cf. https://github.com/oven-sh/bun/blob/ma in/src/bun.js/ws.exports.js ● WebSocket Client ○ built-in WebSocket client is used, instead of ws.WebSocket ● WebSocket Sever ○ ws.WebSocketServer exist, but not implemented yet. ■ exception in constructor. ○ ServerWebSocket is available ■ used from Bun.serve() ■ described in README.md ● Bun でも npm モジュールの wsが使えるよう に見える ● 実は npm モジュールは利用されていない ○ ※ ws をインストールしなくても使える ○ 参考 https://github.com/oven-sh/bun/blob/ma in/src/bun.js/ws.exports.js ● WebSocket クライアント ○ ws.WebSocketの代わりにBun組み込みの WebSocketクライアントが使われる ● WebSocket サーバー ○ ws.WebSockerServerに対応する組み込み サーバーは未実装 ■ コンストラクタで例外を投げるだけ ○ 代わりに、ServerWebSocketを使う ■ Bun.serve() から利用する ■ ※README.md に書いてある
Tips1 : using send() in open handler of ServerWebSocket ● Using send() in websocket open() handler cause disconnect ○ → issue #1469 ● Tips1: Workaround (choose a or b) ○ (a) stop using send() in open() ○ (b) use setTimeout() for send() ● Precondition ○ Only Bun Server - Bun Client ○ NOT necessary for other case ■ Bun Server - Node.js Client ■ Bun Server - Deno Client ■ Bun Server - Browsers ■ Node.js Server - Bun Client ■ Deno Sever - Bun Client ● websocketのopenイベントハンドラ内で send() を使うと、 切断される ○ → issue #1469 ● Tips1: 対策 ( a または b) ○ (a) openイベントハンドラでは send()を使わな い ○ (b) setTimeout() を入れてから send() を使う ● 前提条件 ○ Bun Server - Bun Client の組合せだけ発生 ○ 他のケースでは不要 ■ Bun Server - Node.js Client ■ Bun Server - Deno Client ■ Bun Server - Browsers ■ Node.js Server - Bun Client ■ Deno Sever - Bun Client
Tips2: localhost reslovging in IPv6 / IPv4 ● when using "localhost" in client, fails to connect ○ → Issue #1389 ○ "localhost" is resolved in IPv6 address [::1]. ○ Server is listing on "0.0.0.0" (IPv4) ● Tips2 : Workaround (one of a or b) ○ (a) Use "127.0.0.1" in the client. (IPv4) ○ (b) Use host option in the server (undocmented) - host : "localhost" (IPv6) ● Precondition ○ Only Bun Server - Bun Client ■ NOT necessary for other case ○ Only in some environment (Ubuntu 22.04) ■ NOT necessary for Ubuntu 20.04, macOS 12 ● クライアント側で接続先に "localhost" を指定す ると、接続できない ○ → Issue #1389 ○ "localhost" は IPv6の[::1]に解決される ○ サーバーは "0.0.0.0" (IPv4) でリッスン中 ● Tips2 : 回避策 (a, b のどちらか一方だけ ) ○ (a) クライアント側で"127.0.0.1"を指定(IPv4) ○ (b) サーバー側でパラメータを指定 ■ host : "localhost" (IPv6) ● 前提条件 ○ Bun Server - Bun Client の組合せだけ発生 ■ 他のケースでは不要 ○ 特定の環境だけ必要(Ubuntu 22.04 など) ■ Ubuntu 20.04, macOS 12 では不要
Using WebAssembly module in Bun // simple example to call wasm const fs = require( "fs"); const content = fs.readFileSync( "./func.wasm" ); WebAssembly.compile(content) .then((module) => { const lib = new WebAssembly.Instance(module, { env: {},}).exports; // --- call func --- const ret = lib.func(); console.log(ret); // 42 }) .catch((e) => { console.error( "ERROR:", e) }); console.warn( "--- end ---" ); ● Node.js works well ● Bun process exit before calling wasm function. ○ does not wait for WebAssembly.compile(), ● Node.js ではうまく動く ● Bunのプロセスは、WebAssembly.compile()の完 了を待たずに終了してしまう。そのため wasmモ ジュールの関数を呼び出せない → Issue #1189 Tips(workaround) ● use setTimeout() , or just use await ○ Top level await is enabled in Bun. (even not .mjs) ● setTimeout()で待つか、単に await すればOK
Thank you! WebSocket Server/Client ● Trivia ○ ws module works in Client ○ use ServerWebSocket for Server ■ subscirbe/unsubscribe, publish ● Precondition: ○ in case of Bun server - Bun client ● Tips 1 ○ DO NOT use send() in open() handler of server ○ If you want, use with setTimeout() ● Tips 2: in Ubuntu 22.04 only ○ (a) use IPv4 address "127.0.0.1" in client ○ (b) use " host: 'localhost' " in server ■ only one of a/b, NOT both using WebAssembly module - just use await - top level await is available even in .js - or, use setTimeout() A staff of WebRTC Meetup Tokyo