Dots

ブログとか

original-piping-server

AA電話のために、簡易的なPiping Serverを作った。


他所のPiping Serverを一時的にお借りして、WebRTCのシグナリングに使っていたが、ずっと使うのは申し訳ないので、自分でPiping Serverを構築した。

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