新規投稿のお知らせを受信されたい方は、サブスクリプションをご登録ください:

Workers用TCPおよびSocketsとの接続

2021/11/15

4 分で読了
Making connections with TCP and Sockets for Workers

本日、さらに多くのTCP、UDP、QUIC-ベースのプロトコルをCloudflare Workersでサポートするための、APIおよびインフラストラクチャの開発について発表できることを非常に喜ばしく思います。リリース後、これらの新しい機能を使用すると、WorkerまたはDurable Objectに対する非-HTTPソケット接続を、HTTPおよびWebSocketsを使用するのと同じように簡単に使用することができるようになります。

難しい設定をせずに、Cloudflare Workersでは標準fetchおよびWebSocket APIの使用によってHTTPとWebSocket接続を開く機能がサポートされます。Workersで動作させるためにわずかに内部を変更した、1つのを開発しました。これは市販のドライバ(この例では、Deno-ベースのPostgresクライアントドライバ)を使用して、セキュアなCloudflare Tunnel全体でWebSocketを介しリモートPostgresサーバーと通信します。

import { Client } from './driver/postgres/postgres'

export default {
  async fetch(request: Request, env, ctx: ExecutionContext) {
    try {
      const client = new Client({
        user: 'postgres',
        database: 'postgres',
        hostname: 'https://db.example.com',
        password: '',
        port: 5432,
      })
      await client.connect()
      const result = await client.queryArray('SELECT * FROM users WHERE uuid=1;')
      ctx.waitUntil(client.end())
      return new Response(JSON.stringify(result.rows[0]))
    } catch (e) {
      return new Response((e as Error).message)
    }
  },
}

この例は、Deno-固有のTCPソケットAPIを使用するPostgresクライアントドライバのビットを、標準fetceおよびWebSocket APIに置換することによって動作します。次に、Postgresサーバーに隣接して実行されるリモートCloudflare TunnelデーモンとのWebSocket接続を確立し、事実上のTCP-over-WebSocketsを確立しました。

Connecting to a backend data center via a Cloudflare Tunnel

この例を作成して (Cloudflare Workersのランタイムを全く変更せずに) Postgresサーバーと効果的かつ効率的に通信できたという事実は印象的なことですが、そのアプローチには制限があります。1つ目の制限は、そのソリューションでは、WebSocketトンネルを確立して維持するために追加のインフラストラクチャ (この場合は、Postgresサーバーに隣接して実行されるCloudflare Tunnelデーモンのインスタンス) が必要なことです。そのデーモンをお客様に提供できることは確かに喜ばしいことですが、そのコンポーネントを全く必要としないならもっと良いでしょう。2つ目は、自身がTCP上でHTTPを介してトンネリングする、WebSockets上でのTCPのトンネリングは、あまり最適とは言えないことです。動作はするものの、もっと良い方法があります。

Cloudflare Workersから接続する

現在、JavaScriptにはソケット接続のための標準APIがありません。それを変えたいと思います。

Node.jsを使用したことがある方は、net.Socketnet.TLSSocketオブジェクトについて良く知っているでしょう。Denoを使用しているのであれば最近、Deno.connect()Deno.connectTLS() APIが導入されたことについてご存じかも知れません。これらのAPIを見るとすぐにわかりますが、全く同じことを実行しているにも関わらず、それらは互いに大きく異なっています。

Workers内からソケット接続を開いて使用する機能を追加することに決めたとき、私たちの総意として他のプラットフォームで提供されるAPIと異なる、他の非標準のプラットフォーム固有のAPIをそれ以上開発することには全く興味がありませんでした。そのため、開発するランタイムに関係なく動作する、新しい(そして最終的には標準化される) APIと連携するため、ソケット機能を必要とするすべてのJavaScriptランタイムにまで範囲を広げます。

次のものは、単純なTCPクライアント接続から開いて読み取ることを念頭に置いた荒削りの例です。

const socket = new Socket({
  remote: { address: '123.123.123.123', port: 1234 },
})
for await (const chunk of socket.readable)
  console.log(chunk)

または、この例では、UDPを使用して単純な「hello world」パケットを送信します。

const socket = new Socket({
  type: 'udp',
  remote: { address: '123.123.123.123', port: 1234 },
});
const enc = new TextEncoder();
const writer = socket.writable.getWriter();
await writer.write(enc.encode('hello world'));
await writer.close();

APIは一般的に、TLSの有無にかかわらず、TCP、UDP、QUICに対して、クライアントおよびサーバー側の両方で十分動作するように設計されており、単一のJavaScriptランタイム固有のどのメカニズムにも依存しません。それはEventTargetReadableStreamWritableStreamAbortSignalpromisesなど、既存の広くサポートされるWebプラットフォーム標準を基準にしています。既にfetch() API、サービスWorkers、およびasync/awitを使用するpromisesに精通した開発者に、良く知られたものとなるでしょう。

interface Socket : EventTarget {
  constructor(object SocketInit);

  Promise<undefined> update(object SocketInit);

  readonly attribute ReadableStream readable;
  readonly attribute WritableStream writable;
  
  readonly attribute Promise<undefined> ready;
  readonly attribute Promise<undefined> closed;

  Promise<undefined> abort(optional any reason);
  readonly attribute AbortSignal signal;
 
  readonly attribute SocketStats stats;
  readonly attribute SocketInfo info;
}

これは現時点では単なる提案に過ぎず、機能がWorkersで提供される頃には詳細が上記の例から変更される可能性があります。開発者がコードを実行する場所に関係なく構築するための一貫した基盤を持つことができるように、他のプラットフォームがこの新しいAPIの開発とサポートの取り組みに加わることを願っています。

Socket Workersの導入

ソケットクライアント接続の機能についてはまだこのストーリーの中間地点にすぎません。

最初にこれらの機能を追加することについて話し始めたとき、以下のような明確な質問が寄せられました。非HTTPプロトコルを使用したWorkersへの接続はどうですか? Workerをいくつかの他のバックエンドデータベースに接続する機能を持つようにするだけでなく、データベース全体をedge上に実装する場合は、Workers内部に、それに接続する非HTTPクライアントを配置することはできますか? さらに言えば、SMTPサーバーをWorkers内に実装することはできますか? または、MQTTメッセージキューはどうですか? または完全なVoIPプラットフォームはどうですか? またはパケットフィルタ、変換、インスペクタ、またはプロトコルトランスコーダの実装はどうですか?

WorkersはHTTPとWebSocketsだけに留めておくにはあまりにも強力なので、まもなくSocket Workersを導入します。これは、HTTPを使用せず、未加工のTCP、UDP、またはQUICプロトコルを直接使用して接続することができるWorkersです。

この新しいWorkers機能はどのようなものですか?多くの詳細はまだ未定ですが、その発想は現在"fetch"イベントが動作するのとほぼ同じ方法で"connect"イベントを理解し応答するWorkersスクリプトをデプロイすることです。重要なこととして、これは以下のようにクライアント接続に対して開発されたものと同じ共通ソケットAPI上に基づいて構築されます。

addEventListener('connect', (event) => {
  const enc = new TextEncoder();
  const writer = event.socket.writable.getWriter();
  writer.write(enc.encode('Hello World'));
  writer.close();
});

次の手順(および実施要請)

JavaScriptおよびSocket Workers用の新しいソケットAPIの開発は活発に進められており、まずWorkersがバックエンド上のデータベースにさらに効率的な方法で接続できるようにすることに焦点が当てられています — ユーザーはこちらからサインアップしてDatabase ConnectorsとSocket Workersへのアクセスの待機リストに参加することができます。初期からのユーザー、および技術パートナーと共に作業して、これらの新しい機能を開発、修正、およびテストできることを嬉しく思います。

リリース後は、Socket Workersによって、Cloudflareネットワークエッジにデプロイ可能なタイプのインテリジェントな分散アプリケーションの門が広く開かれることを期待しており、あなたがそれを使って作成するものを見ることを楽しみにしています。

Cloudflareは企業ネットワーク全体を保護し、お客様がインターネット規模のアプリケーションを効率的に構築し、あらゆるWebサイトやインターネットアプリケーションを高速化し、DDoS攻撃を退けハッカーの侵入を防ぎゼロトラスト導入を推進できるようお手伝いしています。

ご使用のデバイスから1.1.1.1 にアクセスし、インターネットを高速化し安全性を高めるCloudflareの無料アプリをご利用ください。

より良いインターネットの構築支援という当社の使命について、詳しくはこちらをご覧ください。新たなキャリアの方向性を模索中の方は、当社の求人情報をご覧ください。
Full Stack Week (JP)Cloudflare Workers (JP)QUIC (JP)日本語Product News (JP)Serverless (JP)

Xでフォロー

Brendan Coll|@_mrbbot
Jonathan Kuperman|@jkup
Cloudflare|@cloudflare

関連ブログ投稿

2021年11月20日 13:59

ネットワークパフォーマンスの最新情報:Full Stack Week

2か月と少し前に、世界中のラストワンマイルネットワークの広範なベンチマーク結果を共有しました。さまざまなテスト (TCP接続時間、最初の1バイトを受信するまでの時間(TTFB)、最後の1バイトを受信するまでの時間(TTLB))、また、さまざ...

2021年11月19日 14:00

Cloudflare Workersで、StripeのJavaScript SDKをネイティブサポート

アプリの中で支払いを処理することは、オンラインビジネスを構築する上で非常に重要です。多くの開発者が決済のプラットフォームに選ぶのがStripeです。私が初めてStripeに出会ったのは約7年前ですが、このサービスは単純な支払い処理をはるかに超えて進化しています。...

2021年11月19日 13:59

Cloudflareで次の動画アプリケーションを構築

歴史的に、動画アプリケーションの構築は非常に難しいものでした。動画の録画、エンコード、そして再生の裏には多くの複雑な技術があります。幸いなことに、Cloudflare Streamではすべての難しい部分を取り除くことで、カスタム動画やストリーミングアプリケーションを簡単に構築できます...

2021年11月19日 13:59

CloudflareスタックでのオープンソースCMS:紹介記事

Cloudflareのドキュメントは、コンセプトを学習したり、APIの使用上の注意を確認したりする場合や、APIやコンセプトを説明するための簡潔なスニペットが必要な場合に役立つ資料です。しかし、その資料が網羅的であるとしても、Cloudflare Workersプラットフォームの新規ユーザーは、...