ブログとか
2025-06-26
AA電話のために、簡易的なPiping Serverを作った。
他所のPiping Serverを一時的にお借りして、WebRTCのシグナリングに使っていたが、ずっと使うのは申し訳ないので、自分でPiping Serverを構築した。
piping serverは、データを転送するサーバーで、インターネットに繋がっているコンピュータ同士で、URLだけを共有することで、データをやり取りできる、割とシンプルな仕組みのサーバー。
他所のPiping Serverを使っておいた割に自分勝手ではあるが、piping server を公開した場合、意図的に大量データを送信されると、サーバーはダウンしないが、俺に大量に課金されてしまう。
GCPやAWSなどのクラウドサービスでは、転送データ量に応じて課金される。 データ量といっても、各社クラウドの中に入っていく方向の通信は無料。 逆に、外に出ていく方向の通信は課金されるということにだいたいなっている。
条件によっては無料枠などもあるが、毎月10GiBで、1.2$ 程度はかかる。
piping server 経由でデータを送信すると、仕組み的には簡単に1GiB以上のデータを送信できてしまう。
意図的に大量のデータを送信されると、サーバーはダウンしないが、管理者であるこちらに大量に課金されてしまう。
公開すると勝手に使われるのを前提として、単位時間あたりのリクエスト数や、データ量、トータルの転送データ量などに制限をかけた。
このようにデータを送信する。
# URLは仮
$ echo "hello world" | curl -X PUT https://localhost:3000/p/xxx &
$ curl https://localhost:3000/p/xxx
hello world
送信側が先でもいいし、受信側が先でもいい。
当然クライアントがキャンセルすることもある。
curl コマンド実行中にCTRL+Cを押すと、切断されるが、これをサーバー側でうまいこと処理するのが結構面倒くさかった。
%%{init: {'theme':'dark', 'themeVariables': { 'primaryColor': '#4a90e2', 'primaryTextColor': '#ffffff', 'primaryBorderColor': '#6bb6ff', 'lineColor': '#8cc8ff', 'secondaryColor': '#ed8936', 'tertiaryColor': '#9f7aea', 'background': '#2d3748', 'mainBkg': '#2d3748', 'secondBkg': '#4a5568', 'actorBkg': '#4a90e2', 'actorTextColor': '#ffffff', 'actorLineColor': '#6bb6ff', 'signalColor': '#ffffff', 'signalTextColor': '#ffffff', 'c0': '#4a90e2', 'c1': '#9f7aea', 'c2': '#ed8936', 'c3': '#48bb78'}}}%%
sequenceDiagram
participant S as Sender
participant PS as Piping Server
participant R as Receiver
participant Timer as Cleanup Timer
Note over PS: Connection Disconnection Detection
%% Normal Flow
rect rgb(25, 77, 51)
Note over S,R: Normal Flow
R->>PS: GET /p/channel
PS->>PS: Create channel entry
S->>PS: POST /p/channel (data)
PS->>PS: Connect & remove entry
PS->>R: Stream data
PS->>S: Status messages
end
%% Disconnection Detection
rect rgb(77, 25, 25)
Note over S,R: Client Disconnection (FIN/RST)
R->>PS: GET /p/channel
PS->>PS: Create channel entry
Note over R: Ctrl+C disconnect
R--xPS: Connection drops
PS->>PS: Drop guard triggers
PS->>PS: Remove channel immediately
S->>PS: POST /p/channel (later)
PS->>PS: No conflict - channel cleaned up
end
%% Aggressive Cleanup
rect rgb(25, 25, 77)
Note over Timer,PS: Cleanup System
loop Every 3 seconds
Timer->>PS: Remove channels > 10s old
end
end
Note over S,R: Key: Drop guards + aggressive cleanup prevent orphaned channels