FreshにWebSocketのFirstクラスサポートが入った

-- Views

June 05, 26

スライド概要

2026/06/03 toranoana.deno #25
虎の穴ラボ オクタニ

Fresh 2.3 に WebSocketのFirst Classサポートが導入。
導入の状況についてサンプルコードと、提供されている使い方の種類を例にとり紹介する。

profile-image

虎の穴ラボ株式会社は、主にとらのあな関連サービスのシステム開発を専門に担う、エンジニアの会社です。

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

ダウンロード

関連スライド

各ページのテキスト
1.

Fresh🍋にWebSocketの First Classサポートが入った 2026/06/03 toranoana.deno #25 虎の穴ラボ オクタニ Copyright (C) 2025 Toranoana Lab Inc. All Rights Reserved.

2.

自己紹介 奥谷 一陽 所属:虎の穴ラボ株式会社 仕事:Fantiaの開発 Ruby on Rails、 React 興味:Deno、TypeScript 最近: ストーン・オーシャンを全部見ました X:@okutann88 github:Octo8080X toranoana.deno 運営の1人 Copyright (C) 2025 Toranoana Lab Inc. All Rights Reserved.

3.

https://deno.com/blog/fresh-2.3 Copyright (C) 2025 Toranoana Lab Inc. All Rights Reserved.

4.

Fresh 2.3 公開 - デフォルトで、クライアントに JSの転送が 0に - トランジション対応 - Vite 統合改善 - 公式ミドルウェア追加 - CSP - IP フィルタリング - Islands のプロパティとして Temporal 関連の型に対応 and more Copyright (C) 2025 Toranoana Lab Inc. All Rights Reserved.

5.

Copyright (C) 2025 Toranoana Lab Inc. All Rights Reserved.

6.

どんな風に書いて使えるのか?を紹介 Copyright (C) 2025 Toranoana Lab Inc. All Rights Reserved.

7.
[beta]
1. 最小構成
import { App, staticFiles } from "fresh";
import { type State } from "./utils.ts";

接続すると

export const app = new App<State>();

「Client connected」を出力

app.use(staticFiles());

メッセージが届くと
「Echo: OOOOO」を返す
接続が閉じると
「Client disconnected」を出力
単一の通信のやりとりであれば
かなりシンプルに記述できる。

app.ws("/ws", {
open(_socket) {
console.log("Client connected");
},
message(socket, event) {
socket.send(`Echo: ${event.data} `);
},
close(_socket, code, reason) {
console.log("Client disconnected", code,
reason);
},
});
app.fsRoutes();

Copyright (C) 2025 Toranoana Lab Inc. All Rights Reserved.

8.

Copyright (C) 2025 Toranoana Lab Inc. All Rights Reserved.

9.
[beta]
2. しばらく接続する
接続したらメッセージを流し続ける
export const app = new App<State>();
app.use(staticFiles());
app.ws("/ws", {
open(_socket) {
console.log("Client connected");
},
message(socket, event) {
socket.send(`Echo: ${event.data} --`);
setInterval(() => {
socket.send(`polling Now: ${ new Date().toLocaleTimeString()}`);
}, 2000);
},
close(_socket, code, reason) {
console.log("Client disconnected", code, reason);
},
});
Copyright (C) 2025 Toranoana Lab Inc. All Rights Reserved.

10.

Copyright (C) 2025 Toranoana Lab Inc. All Rights Reserved.

11.
[beta]
3. ディレクトリルーティングで触る
引数なし、 ctx.upgrade()から socketを共通の変数化して扱える。
用途次第では、このように使いたい人もいるはず
//routes/ws.ts
export const handler = define.handlers({
GET(ctx) {
const { socket, response } = ctx.upgrade();
const randomId = crypto.randomUUID();
socket.onopen = () => {
clients.add(socket);
if (workerTimer) {
return;
}
…

ソースコード全て見たい方 https://www.ccbaxy.xyz/blog/2026/05/30/js115/
Copyright (C) 2025 Toranoana Lab Inc. All Rights Reserved.

12.

ウィンドウ間同期 Copyright (C) 2025 Toranoana Lab Inc. All Rights Reserved.

13.

まとめ Copyright (C) 2025 Toranoana Lab Inc. All Rights Reserved.

14.

まとめ - Fresh に WebSocketのFirstClassサポートが入った - 簡単に書ける .ws() - どのクライアントにも一律に同じものを流す - 1リクエスト 1+n件レスポンスを返す 運用にはマッチ - しかし! - チャットルームを立てるような運用にはミスマッチ? - ctx.upgrade() も併用する。 Copyright (C) 2025 Toranoana Lab Inc. All Rights Reserved.

15.

ありがとうございました Copyright (C) 2025 Toranoana Lab Inc. All Rights Reserved.