$30 off During Our Annual Pro Sale. View Details »
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
自作WebSocket (RFC6455)
Search
Hakkadaikon
December 19, 2025
Programming
0
49
自作WebSocket (RFC6455)
12/18 自社の社内LTで発表した内容
https://github.com/Hakkadaikon/websocket
Hakkadaikon
December 19, 2025
Tweet
Share
More Decks by Hakkadaikon
See All by Hakkadaikon
routstrについて
hakkadaikon
0
89
Nostr x BTC
hakkadaikon
0
32
Blueskyのプラグインを作ってみた
hakkadaikon
1
710
PHP x Nostr
hakkadaikon
0
130
Emacs x Nostr
hakkadaikon
2
330
My Introduction To Nostr
hakkadaikon
0
210
Nostr × C#
hakkadaikon
0
220
思考の速さで使うクライアント ~vimクライアント作ってみた~
hakkadaikon
0
440
ゴリラ.vim #30 ライブコーティング
hakkadaikon
0
98
Other Decks in Programming
See All in Programming
【Streamlit x Snowflake】データ基盤からアプリ開発・AI活用まで、すべてをSnowflake内で実現
ayumu_yamaguchi
1
120
令和最新版Android Studioで化石デバイス向けアプリを作る
arkw
0
410
Why Kotlin? 電子カルテを Kotlin で開発する理由 / Why Kotlin? at Henry
agatan
2
7.3k
ローターアクトEクラブ アメリカンナイト:川端 柚菜 氏(Japan O.K. ローターアクトEクラブ 会長):2720 Japan O.K. ロータリーEクラブ2025年12月1日卓話
2720japanoke
0
730
なあ兄弟、 余白の意味を考えてから UI実装してくれ!
ktcryomm
11
11k
Navigation 3: 적응형 UI를 위한 앱 탐색
fornewid
1
350
AIエンジニアリングのご紹介 / Introduction to AI Engineering
rkaga
8
2.9k
ELYZA_Findy AI Engineering Summit登壇資料_AIコーディング時代に「ちゃんと」やること_toB LLMプロダクト開発舞台裏_20251216
elyza
0
210
著者と進める!『AIと個人開発したくなったらまずCursorで要件定義だ!』
yasunacoffee
0
140
Go コードベースの構成と AI コンテキスト定義
andpad
0
130
堅牢なフロントエンドテスト基盤を構築するために行った取り組み
shogo4131
8
2.4k
FluorTracer / RayTracingCamp11
kugimasa
0
230
Featured
See All Featured
Leading Effective Engineering Teams in the AI Era
addyosmani
9
1.3k
It's Worth the Effort
3n
187
29k
Designing for humans not robots
tammielis
254
26k
Fireside Chat
paigeccino
41
3.7k
Rebuilding a faster, lazier Slack
samanthasiow
85
9.3k
Docker and Python
trallard
47
3.7k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
7.9k
Product Roadmaps are Hard
iamctodd
PRO
55
12k
Principles of Awesome APIs and How to Build Them.
keavy
127
17k
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
Bash Introduction
62gerente
615
210k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.6k
Transcript
⾃作WebSocket (RFC6455) 2025/12/18 発⽕⼤根
[introduce] name = “発⽕⼤根” department = “SRE” hobby = [“卓球🏓”,
“謎解き🔍”] UTF-8 NORMAL main introduce.toml
趣味で作っている WebSocketライブラリの話をします マニアックな話です
WebSocketとは ‧Webサーバーとクライアント間で双⽅向通信をするためのプロトコル ‧⾊々なところで利⽤されている ‧ライブ配信のコメント‧投げ銭 ‧SNS ‧株価取得 ‧オークションの⼊札 ‧etc…
WebSocket を使いたいと思った動機 ‧趣味でやっているSNSがある ‧そのSNSがWebSocketの上で動いている + オープンなプロトコル ‧⾃分でWebSocket サーバーを⽴てたいと思った
Web通信の変遷
OSI 7階層モデル L1 物理層 (ケーブル‧電気信号) L2 データリンク層 (Ethernet, WiFi) L3
ネットワーク層 (IP, ICMP) L4 トランスポート層 (UDP / TCP) L6 プレゼンテーション層 (SSL/TLS) L7 アプリケーション層 (HTTP / WebSocket / SMTP / FTP) L5 セッション層 (HTTPのハンドシェイク)
TCP / IP ‧UDPと違い、コネクションを 確⽴する必要がある ‧プロセスやOS単位で、コネクション を開ける個数が決まっている ‧コネクション数は節約できた⽅が 沢⼭の通信先と通信できる
Web通信の変遷 1 1991年〜 HTTP 0.9 イギリスの物理学者、 ティム‧バーナーズ‧リーが開発 URLを指定してコンテンツをダウンロードするだけの仕組みだった (GETのみ) GET
/index.html
Web通信の変遷 2 1996年〜 HTTP 1.0 [RFC1945] 仕様がRFCで管理されるようになった POSTなど、GET以外のメソッドが⾊々と増えた リクエストごとにTCPのコネクションが張られていた GET
/index.html HTTP/1.0
Web通信の変遷 3 1997年〜 HTTP 1.1 [RFC2068 -> RFC2616 -> RFC7230〜7235
-> RFC9112] 単⼀のTCPコネクションで複数のHTTPリクエストが送れるようになった GET /index.html HTTP/1.1 Host: foo.example.com Connection: keep-alive -> TCPコネクションを使いまわす
Web通信の変遷 4 2011年〜 WebSocket [RFC6445] 単⼀TCPストリームでリクエスト/レスポンスの双⽅向通信ができるようになった HTTP1.1 で動作する GET /resource
HTTP/1.1 Host: example.com Upgrade: websocket Connection: upgrade Sec-WebSocket-Version: 13 Sec-WebSocket-Key: E4WSEcseoWr4csPLS2QJHA==
Web通信の変遷 5 2015年〜 HTTP2.0 [RFC7540 -> RFC7441 -> RFC9113] テキストではなくバイナリのやりとり
(TCP等と同じ) より多くのデータを送れるように
Web通信の変遷 6 2015年〜 SSE (Server Sent Event) [RFC] HTTPでサーバーから通知を送れるようになった (サーバー
-> クライアントの⼀⽅通⾏) HTTP1.1, HTTP2.0で実⾏可能 GET /events HTTP/1.1 Host: example.com Accept: text/event-stream -> 継続的にサーバーからイベントが貰える Cache-Control: no-cache Connection: keep-alive
Web通信の変遷 7 2022年〜 HTTP3.0 [RFC9114] HTTP2.0と同じく、バイナリベースのやりとり TCPではなくQUICの上で動作する QUIC: UDPでTCPのような信頼性を確保する
⾃作 WebSocket
WebSocket の各⾔語のサポート状況 多くの⾔語でWebSocketを使うためのOSSがある & 標準でつかえる⾔語 もある ‧標準で使える⾔語: JavaScript/TypeScript, C#, Java,
etc…
せっかくWebSocketサーバー⽴てるなら ⾃分で”1から”作りたいな...
ということで、今年作ったのが この WebSocket サーバーライブラリ
⾃作WebSocketライブラリの特徴 ‧開発⾔語: C⾔語 (C23) + アセンブラ ‧サポートOS: macOS, Linux ‧ライブラリ依存:
無し (Linuxの場合) ‧機能サポート状況: 右記 (機能的には最低限) opcode support 0x1 (text), 0x2(binary), 0x8 (close), 0xA (pong) TLS support No Sub Protocol No Extensions No Compression / Decode No
⾃作WebSocketの推しポイント
推しポイント 1. C⾔語 + アセンブラによる構成 -> ⾼速 2. 依存ライブラリなし ->
Dockerコンテナ(scratch)にバイナリ1つコピーすれば動作する -> コンパクトなバイナリ/コンテナ (サイズ < 1MB)
C⾔語のメリット ‧50年の歴史があり、情報が多い ‧メモリを直接触れる -> ⽬指そうと思えば、極限まで⾼速化やバイナリ最⼩化を⽬指せる ‧最近よく使われているGo⾔語やZigなども 初期バージョンはCやC++で出来ていた
”外部ライブラリ依存なし”でソフトウェアを作るには 通常、ファイル操作やネットワーク通信を⾏うには カーネルで提供されている関数をシステムコールで呼び出して ⾏う必要がある カーネル 空間 システム コール ユーザー 空間
デバイス ドライバ ネット ワーク カード
”外部ライブラリ依存なし”でソフトウェアを作るには ‧システムコールは libc経由で呼び出すことが多い ‧OSやCPUアーキテクチャの 差異を吸収 -> libcに依存する! カーネル 空間 システム
コール ユーザー 空間 libc (DLL) OSや アーキテクチャ の差異を吸収
”外部ライブラリ依存なし”でソフトウェアを作るには ‧OSやアーキテクチャの 固有の処理を理解して ⾃分でシステムコールを 呼び出す -> libcに依存しない! -> シングルバイナリに出来る! ※Go⾔語はbuiltinでこれをやって
いるのでlibcに依存しない カーネル 空間 システム コール ユーザー 空間 libc (DLL) OSや アーキテクチャ の差異を吸収
システムコール (Linux / x86_64の場合) __linux_x8664_asm_syscall: movq %rdi, %rax movq %rsi,
%rdi movq %rdx, %rsi movq %rcx, %rdx movq %r8, %r10 movq %r9, %r8 syscall ret システムコールを アセンブラで呼ぶ必要がある OSやCPUアーキテクチャで 使うレジスタや書き⽅が変わる
システムコール (Linux / x86_64の場合) syscall (arg1, arg2, arg3, arg4, arg5,
arg6) rdi rsi rdx rcx r8 r9 rax rdi rsi rdx r10 r8 システムコールで 使うレジスタ 引数の値が 渡されるレジスタ syscall レジスタを読み替えて渡す必要がある
システムコール (他のOSの場合) さっき書いたスペック表 ‧開発⾔語: C⾔語 (C23) + アセンブラ ‧サポートOS: macOS,
Linux ‧ライブラリ依存: 無し (Linuxの場合) => これには理由があります ‧機能サポート状況: 右記 (機能的には最低限)
システムコール (macOS の場合) macOSの場合 => システムコールの直接呼びだし / 静的リンク => ⾮推奨
https://developer.apple.com/library/archive/qa/qa1118/_index.html
システムコール (macOS の場合) 同じ理由でGo⾔語もDLL (lib)を使うことに (#17490: 2016/10/18) https://github.com/golang/go/issues/17490
システムコール (Windows の場合) カーネル 空間 システム コール ユーザー 空間 libc
Windows API (DLL) NTDLL (DLL) OSや アーキテクチャ の差異を吸収 ここまではサポートされている
システムコール (Windows の場合) NTDLLの関数やシステムコールの直接呼び出しは⾮推奨 https://learn.microsoft.com/ja-jp/sysinternals/resources/inside-native-applications
どのくらい⾃作したか WebSocketのパーサー / ハンドシェイク(通信確⽴)の他には... ‧ハンドシェイクに必要なHTTP1.1の解釈 (RFC9110 / RFC9112) ‧ デバッグするためのログ出⼒
‧ハンドシェイクに必要な暗号化の関数 (base64 / sha1) ※sha1はパブリックドメインのソースを埋め込み & リファクタ TCP/IPから上のレイヤーは、ほぼ⾃作 (TCP/IPはカーネルの機能を使⽤)
⾃作プロトコルスタックのすすめ ‧HTTPやWebSocketなど、プロトコルについて解像度が上がる => OSS選定の時も役に⽴つ ‧仕様がハッキリしている => 勉強がてら何か作りたい、でも作りたいものがない みたいな⼈にもオススメ
課題
課題 ‧SSL/TLSの⾃作 => ⼀旦断念している ‧暗号系の関数 (楕円曲線暗号など) を⾃作するコストが⾮常に⾼い ‧外部に出すには必須 => 今のところ、テストや内部ネットワーク⽤
‧HTTP1.1にしか対応していない ‧HTTP2.0で動かすには、RFC8441等の実装が必要 ‧HTTP3.0は標準でTLS通信をサポートしているため、実装が難しい
今後の展望 ‧SSL/TLSの⾃作 (いつか) ‧HTTP 2.0 でのWebSocket サポート (RFC8441) ‧WebSocketとしての機能拡充 (NoをYesにしていく)
opcode support 0x1 (text), 0x2(binary), 0x8 (close), 0xA (pong) TLS support No Sub Protocol No Extensions No Compression / Decode No
ご清聴 ありがとうございました