INTEGRITY Документация

TCP-сокеты

Среда выполнения Workers предоставляет connect() API для создания исходящих TCP-соединения из Workers.

Многие протоколы прикладного уровня строятся поверх протокола управления передачей (TCP). Для работы таких протоколов, включая SSH, MQTT, SMTP, FTP, IRC и большинство сетевых протоколов баз данных, в том числе MySQL, PostgreSQL и MongoDB, необходим базовый TCP socket API.

connect()

connect() функция возвращает TCP-сокет с читаемый и для записи поток данных. Это позволяет читать и записывать данные непрерывно, пока соединение остаётся открытым.

connect() предоставляется как Runtime API, и доступ к нему осуществляется путем импорта connect функцию из cloudflare:sockets. Этот процесс похож на импорт встроенных модулей в Node.js. Пример создания TCP-сокета, записи в него и возврата читаемой стороны сокета в качестве ответа приведён в следующем блоке кода:

import { connect } from 'cloudflare:sockets';

export default {
  async fetch(req): Promise<Response> {
    const gopherAddr = { hostname: "gopher.floodgap.com", port: 70 };
    const url = new URL(req.url);

    try {
      const socket = connect(gopherAddr);

      const writer = socket.writable.getWriter()
      const encoder = new TextEncoder();
      const encoded = encoder.encode(url.pathname + "\r\n");
      await writer.write(encoded);
      await writer.close();

      return new Response(socket.readable, { headers: { "Content-Type": "text/plain" } });
    } catch (error) {
      return new Response("Socket connection failed: " + error, { status: 500 });
    }
  }
} satisfies ExportedHandler;

SocketAddress

SocketOptions

SocketInfo

Socket

Оппортунистический TLS (StartTLS)

Многие системы на основе TCP, включая базы данных и почтовые серверы, требуют, чтобы клиенты использовали оппортунистический TLS (также известный как StartTLS) при подключении. В этой схеме клиент сначала создаёт незащищённый TCP-сокет без TLS, а затем повышает его до защищённого TCP-сокета с TLS. Метод connect() API упрощает эту задачу, предоставляя метод startTls(), который возвращает новый Socket экземпляр, использующий TLS:

import { connect } from "cloudflare:sockets"

const address = {
  hostname: "example-postgres-db.com",
  port: 5432
};
const socket = connect(address, { secureTransport: "starttls" });
const secureSocket = socket.startTls();

Обработка ошибок

Чтобы обработать ошибки при создании нового TCP-сокета, чтении из сокета или записи в сокет, оберните эти вызовы в try...catch блоки инструкции. Следующий пример открывает соединение с Google.com, инициирует HTTP-запрос и возвращает ответ. Если это не удаётся и выбрасывается исключение, возвращается 500 ответ:

import { connect } from 'cloudflare:sockets';
const connectionUrl = { hostname: "google.com", port: 80 };
export interface Env { }
export default {
  async fetch(req, env, ctx): Promise<Response> {
    try {
      const socket = connect(connectionUrl);
      const writer = socket.writable.getWriter();
      const encoder = new TextEncoder();
      const encoded = encoder.encode("GET / HTTP/1.0\r\n\r\n");
      await writer.write(encoded);
      await writer.close();

      return new Response(socket.readable, { headers: { "Content-Type": "text/plain" } });
    } catch (error) {
      return new Response(`Socket connection failed: ${error}`, { status: 500 });
    }
  }
} satisfies ExportedHandler<Env>;

Закрытие TCP-соединений

Закрыть TCP соединение можно, вызвав close() для сокета. Это закроет обе стороны сокета: и читаемую, и записываемую.

import { connect } from "cloudflare:sockets"

const socket = connect({ hostname: "my-url.com", port: 70 });
const reader = socket.readable.getReader();
socket.close();

// After close() is called, you can no longer read from the readable side of the socket
const reader = socket.readable.getReader(); // This fails

Особенности

Устранение неполадок

Ознакомьтесь с описанием типичных сообщений об ошибках, которые могут появиться при работе с TCP Sockets, узнайте, что они означают и как их устранить.

proxy request failed, cannot connect to the specified address

Ваш сокет подключается к адресу, который запрещён. Примеры запрещённых адресов включают IP-адреса Cloudflare, localhost, и IP-адреса частной сети.

Если вам нужно подключаться к адресам на порту 80 или 443 чтобы выполнять HTTP-запросы, используйте fetch.

TCP Loop detected

Ваш сокет подключается обратно к Worker, который инициировал исходящее соединение. Иными словами, Worker подключается сам к себе. В настоящее время это не поддерживается.

Connections to port 25 are prohibited

Ваш сокет подключается к адресу на порте 25. Обычно этот порт используется почтовыми серверами SMTP. Workers не может создавать исходящие подключения через порт 25. Рассмотрите возможность использовать Cloudflare Email Workers взамен.