Hướng Dẫn Sử Dụng
Проверка прокси для WebSocket wss:// с помощью Node.js и диагностика ошибок

Содержание
Зачем отдельно проверять прокси для WebSocket?
Прокси, через который открываются HTTPS-сайты, не обязательно способен стабильно поддерживать защищённое WebSocket-соединение. Для чатов, уведомлений и панелей мониторинга в реальном времени важно не только успешно установить соединение, но и обеспечить стабильный обмен данными в течение длительного времени.
Чтобы проверить поддержку WebSocket прокси-сервером, необходимо проверить туннель через прокси, установление TLS-соединения, рукопожатие WebSocket и передачу данных после открытия соединения. В статье используется Node.js для разделения этих этапов, что помогает определить истинную причину сбоя, а не списывать любые ошибки на прокси.
Как прокси обрабатывает соединения wss://?
wss:// — это WebSocket поверх TLS. В типичной схеме с HTTP-прокси клиент запрашивает у прокси создание туннеля к целевому серверу методом CONNECT. После принятия запроса на создание туннеля клиент устанавливает TLS-соединение с сервером, а затем отправляет запрос рукопожатия WebSocket внутри зашифрованного соединения.
Таким образом, HTTP-прокси не обязательно должен понимать содержимое WebSocket, чтобы передавать трафик wss://. Однако на работу соединения могут влиять политики доступа к целевым адресам, аутентификация, тайм-ауты и ограничения прокси на количество соединений.
- HTTP-прокси: обычно использует CONNECT для создания туннеля к целевому адресу wss://.
- HTTPS-прокси: соединение от клиента до прокси также защищено TLS; это отдельный уровень, независимый от TLS-соединения с целевым сервером.
- SOCKS-прокси: передаёт TCP-соединение с помощью протокола SOCKS вместо HTTP CONNECT.
- Обратный прокси: располагается перед сервером приложения; ошибки настройки передачи WebSocket на этом уровне возможны даже при корректной работе прокси на стороне клиента.
Подготовка среды для проверки wss-прокси в Node.js
Установите необходимые библиотеки следующей командой:
npm install ws https-proxy-agent socks-proxy-agent
В примере используется файл check-wss.mjs, соответствующий синтаксису ES-модулей. Используйте конечную точку WebSocket, которой вы управляете или которую вам разрешено тестировать, с действительным сертификатом и поддержкой нужного протокола приложения.
Программа получает настройки через переменные окружения:
- WSS_URL: адрес wss:// с корректным путём и необходимыми параметрами.
- PROXY_URL: URL прокси, включающий протокол, сервер, порт и учётные данные, если они требуются.
- TEST_TIMEOUT_MS: выбранное оператором время ожидания в миллисекундах.
Не сохраняйте пароль прокси в исходном коде. Если имя пользователя или пароль содержат специальные символы, корректно кодируйте каждый компонент при формировании URL. При записи журналов скрывайте учётные данные, токены и конфиденциальные параметры.
Код Node.js для проверки соединения и ответа Pong
Следующий пример предназначен для HTTP- или HTTPS-прокси. Каждый фрагмент кода представлен отдельным абзацем; последовательно скопируйте их в один файл check-wss.mjs.
import WebSocket from 'ws'; import { HttpsProxyAgent } from 'https-proxy-agent'; import { randomUUID } from 'node:crypto';
const target = new URL(process.env.WSS_URL); const proxy = new URL(process.env.PROXY_URL); const timeout = Number(process.env.TEST_TIMEOUT_MS); if (target.protocol !== 'wss:') throw new Error('WSS_URL должен использовать wss://'); if (!['http:', 'https:'].includes(proxy.protocol)) throw new Error('Для этого примера требуется HTTP- или HTTPS-прокси'); if (!Number.isSafeInteger(timeout) || timeout <= 0) throw new Error('TEST_TIMEOUT_MS должен быть положительным целым числом');
const agent = new HttpsProxyAgent(proxy); const token = randomUUID(); let stage = 'connecting'; let finished = false; let timer; const ws = new WebSocket(target, { agent, handshakeTimeout: timeout });
function finish(ok, message) { if (finished) return; finished = true; clearTimeout(timer); console.log(JSON.stringify({ ok, stage, message })); process.exitCode = ok ? 0 : 1; ws.terminate(); agent.destroy(); }
timer = setTimeout(() => finish(false, 'Истекло время ожидания, заданное оператором'), timeout); ws.on('open', () => { stage = 'waiting-pong'; console.log('Рукопожатие WebSocket завершено'); ws.ping(token); }); ws.on('pong', data => { if (data.toString() === token) finish(true, 'Получен Pong, соответствующий Ping, отправленному через соединение'); });
ws.on('unexpected-response', (request, response) => { finish(false, 'HTTP-ответ не завершил рукопожатие WebSocket: ' + response.statusCode); response.destroy(); }); ws.on('error', error => finish(false, [error.code, error.message].filter(Boolean).join(': '))); ws.on('close', (code, reason) => { if (!finished) finish(false, 'Соединение закрыто: ' + code + ' ' + reason.toString()); });
После настройки переменных окружения в оболочке или средстве управления процессами выполните node check-wss.mjs. Не сохраняйте полную команду с паролем в общей истории команд оболочки.
Как интерпретировать результат
Событие open подтверждает завершение рукопожатия WebSocket. Pong с содержимым, совпадающим с Ping, дополнительно подтверждает, что управляющие кадры прошли по соединению в обоих направлениях. Код использует terminate() для завершения короткой проверки, а не в качестве примера штатного закрытия соединения в рабочем приложении.
Ping/Pong не заменяет проверку бизнес-логики. Успешный результат ещё не доказывает, что работают вход в систему, подписка на каналы или получение событий. И наоборот, отсутствие Pong само по себе не позволяет сделать вывод, что прокси не поддерживает WebSocket; необходимо проверить сервер, нагрузку на систему и выбранное время ожидания.
Если используется SOCKS-прокси
Замените импорт и создание агента на import { SocksProxyAgent } from 'socks-proxy-agent'; и const agent = new SocksProxyAgent(proxy);. Также измените проверку протокола, чтобы разрешить соответствующий тип SOCKS.
В этой библиотеке socks5:// выполняет разрешение имени целевого сервера на стороне клиента, а socks5h:// передаёт имя целевого сервера прокси для разрешения. Это различие важно, если в двух средах отличаются DNS или доступность сетевых ресурсов.
Как убедиться, что соединение действительно проходит через прокси
Не следует считать, что библиотека будет использовать прокси только потому, что в операционной системе заданы соответствующие переменные окружения. В приведённом примере агент передаётся непосредственно в WebSocket, чтобы явно задать маршрут соединения.
- Сопоставьте журналы CONNECT или журналы сеансов соединений на прокси, если у вас есть к ним доступ.
- Проверьте исходный адрес, который видит инфраструктура целевого сервера.
- Используйте контролируемую конечную точку, чтобы связать журналы клиента и сервера идентификатором корреляции.
- В тестовой среде попробуйте указать неработающий прокси: программа должна сообщить об ошибке, а не автоматически переключиться на прямое соединение.
Если сервер находится за обратным прокси или балансировщиком нагрузки, исходный адрес, видимый приложению, может принадлежать промежуточному узлу. В таком случае необходимо сопоставлять журналы в той точке, которая непосредственно принимает соединение.
Диагностика ошибок WebSocket через прокси по этапам
Ошибки подключения к прокси
ENOTFOUND обычно связан с разрешением имён; ECONNREFUSED означает, что соединение отклонено; ETIMEDOUT указывает на истечение времени ожидания сетевой операции. Прежде чем устранять проблему, нужно определить, на каком участке возникла ошибка: клиент–прокси или прокси–целевой сервер.
Проверьте имя хоста, порт, протокол, сетевой доступ и состояние службы прокси. Неверный выбор протокола между HTTP, HTTPS и SOCKS может привести к сбою уже на начальном этапе соединения.
Ошибки аутентификации или создания туннеля
Если прокси требует аутентификацию, проверьте имя пользователя, пароль, кодирование URL и поддерживаемый агентом способ аутентификации. Прокси в корпоративной среде может требовать механизм, для которого недостаточно указать обычные учётные данные в URL.
Создание туннеля также может быть отклонено из-за политики доступа к целевым адресам или ограничений учётной записи. Сопоставьте журналы прокси, прежде чем делать вывод, что весь сервис не поддерживает wss://.
Ошибки сертификатов TLS
Ошибки TLS могут возникать при подключении к HTTPS-прокси или при проверке сервера WebSocket. Типичные причины — неполная цепочка сертификатов, несовпадение имени хоста, истёкший срок действия сертификата или отсутствие доверия к внутреннему центру сертификации.
Не отключайте проверку сертификатов ради успешного результата теста. Необходимо исправить настройку сертификатов или добавить центр сертификации, одобренный администратором. Если используется HTTPS-прокси, точно определите, на каком уровне TLS возникает ошибка.
HTTP-ответ получен, но WebSocket не открывается
Событие unexpected-response означает, что получен HTTP-ответ, который не завершает рукопожатие WebSocket. Проверьте URL, путь, перенаправления, сеанс входа, Origin и подпротокол в соответствии с документацией сервера.
Ответ может исходить от прокси, обратного прокси или целевого приложения. Не определяйте источник только по коду состояния; необходимо сопоставить журналы и сведения об ответе. Если приложение требует заголовок аутентификации, корректно добавьте его в параметры подключения, не записывая секретное значение в журнал.
Соединение открывается, затем закрывается или перестаёт получать данные
Эта группа ошибок часто связана с тайм-аутом бездействия, heartbeat, истечением срока действия сеанса аутентификации, ограничениями соединений или закрытием сеанса приложением. Записывайте время открытия, время последнего получения данных, код и причину закрытия.
Код закрытия, указывающий на нештатное завершение, не позволяет определить устройство, вызвавшее сбой. Сопоставьте события за один и тот же момент времени на клиенте, прокси и сервере, чтобы найти участок разрыва.
Проверка стабильности приложений реального времени
После проверки Ping/Pong добавьте проверку бизнес-сценария с тестовой учётной записью: аутентификацию, подписку на канал и получение события с идентификатором корреляции. Не отправляйте произвольные сообщения, пока не изучите протокол приложения.
- Получите контрольный результат: проверьте одну и ту же конечную точку напрямую и через прокси, если это разрешено сетевой политикой.
- Проверьте режим бездействия: поддерживайте сеанс в течение времени, соответствующего реальным потребностям, чтобы наблюдать за закрытием соединения.
- Проверьте heartbeat: различайте Ping/Pong WebSocket и heartbeat-сообщения на уровне приложения.
- Проверьте восстановление: убедитесь, что после разрыва выполняются повторное подключение, повторная аутентификация и повторная подписка на каналы.
- Проведите контролируемое нагрузочное тестирование: увеличивайте количество соединений только в разрешённых пределах и следите за ресурсами обеих сторон.
Не устанавливайте слишком короткий интервал heartbeat в попытке устранить все ошибки. Подходящее значение должно учитывать политику сервера, тайм-ауты промежуточных узлов и эксплуатационные затраты.
Заключение
Надёжная проверка прокси для WebSocket должна подтверждать маршрут соединения, успешное установление TLS, открытие WebSocket и передачу данных в обоих направлениях. Для реального приложения также необходимо проверить бизнес-логику и способность поддерживать сеанс.
При возникновении ошибок WebSocket через прокси классифицируйте их по этапам, а не меняйте сразу множество настроек. Такой подход помогает точно определить, связана ли ошибка с прокси, сертификатом, обратным прокси или приложением, и сохранить необходимые требования безопасности.
Похожие статьи
Хватит читать — пора подключить настоящий прокси?
Residential, ISP, Datacenter или Mobile прокси — готовы за пару минут.
Смотреть продукты