python — перенаправить поток октетов в Apache, используя PHP или Django

У меня есть веб-сервер, который обслуживает клиента с потоком октетов через порт 20000 (на самом деле это сервер socket.io, размещенный в node.js). Это выполняется на учетной записи общего хостинга с обычным сервером Apache, работающим на порту 80 (это нельзя отключить, поэтому сервер socket.io находится на порту 20000). Из-за брандмауэров и тому подобного я не могу ожидать, что пользователь сможет подключиться к порту 20000 (или к любому другому, кроме 80). Итак, как я могу обслуживать клиента с потоком октетов, генерируемым сервером socket.io с сервера Apache (вроде как обратный прокси-сервер)? К сожалению, я не могу использовать mod_proxy на своем сервере Apache, учитывая ограничения моего плана хостинга. Я думал, что смогу сделать это с помощью PHP-страницы, которая каким-то образом открывает сокет.

Обновить: У меня также есть Django для Python 3, установленный на моем сервере, что может быть полезно. Обратите внимание, что прокси-сервер не может просто запросить целевую страницу и отправить ее обратно клиенту, поскольку данные должны передаваться в режиме реального времени.

6

Решение

«Это не может просто обслуживать целевую страницу назад» … это не так, потому что это все, что HTTP-прокси. Большинство протокольных прокси используют сокет (вместо файла или канала) и просто копируют данные из сокета в сокет. Прокси-сервер HTTP делает то же самое, за исключением того, что для каждого HTTP-запроса требуется рукопожатие, поэтому прокси-серверу потребуется несколько пакетов назад и вперед, прежде чем они достигнут полезной нагрузки. Вы можете очень легко создать HTTP GET-прокси в django. POST-прокси потребуется дополнительная работа.

Я не знаком с Socket.IO, но после исследования … как работает socket.io? … похоже, он использует только «старые» функции HTTP и запускает все как REST. REST инкапсулируется как транспорт внутри постоянного сокета.

Если вы искали прокси TCP или IP-уровня в Django, этого не произойдет. Ваш сервер Apache, а затем WSGI / CGI / все, что закрывает от вас сокет TCP. Единственный способ получить к нему доступ — получить достаточные права доступа к этим частям сервера.

Вот что я бы сделал … В django создайте шаблон url, который захватывает файл socket.io api, и подключите его к представлению, которое выполняет что-то вроде следующего (непроверенный псевдокод):

import urllib2, mimetypes
from django.http import HttpResponse

def ForwardToSocketIO(request):
# Capture the URL pattern
path = request.get_full_path()

# Create a URL opener
response = urllib2.urlopen('http://localhost:20000%s' % path)

# Capture and return response
django_response = HttpResponse(response.read())
django_response['Content-Type'] = 'octet-stream'

return django_response

Надеюсь это поможет. У меня нет потока октетов, поэтому извиняюсь за то, что не тестировал.

2

Другие решения

Кажется возможным, а не невозможным. Я не делал этого раньше, но знаю, как это сделать, но, опять же, я не знаю влияния Firewall на открытие и закрытие портов. Основная идея о том, чтобы делать что-то:

Получите ваш запрос от порта 80, чтобы сделать что-то, и для ответа на этот запрос используйте другой порт для связи с клиентом. Это стало бы туннелем для получения запроса от одного порта и получения ответа от другого порта. Только одна вещь должна быть должным образом позаботилась о том, чтобы разорвать соединение как можно скорее, как только цель будет решена, если только это не приведет к загрузке памяти на сервере.

С помощью приведенного ниже примера вы можете делать вышеперечисленные вещи, но предлагать их использовать с осторожностью и после надлежащего тестирования.

ссылка: Программирование с помощью сокетов через PHP

В этом примере показан простой сервер обратной связи. Измените адрес и переменные порта в соответствии с вашими настройками и выполните. Затем вы можете подключиться к серверу с помощью команды, аналогичной: telnet 192.168.1.53 10000 (где адрес и порт соответствуют вашим настройкам). Все, что вы введете, будет выведено на серверную часть и отправлено вам обратно. Чтобы отключиться, введите «выйти».

<?php
error_reporting(E_ALL);

echo "<h2>TCP/IP Connection</h2>\n";

/* Get the port for the WWW service. */
$service_port = getservbyname('www', 'tcp');

/* Get the IP address for the target host. */
$address = gethostbyname('www.example.com');

/* Create a TCP/IP socket. */
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
echo "socket_create() failed: reason: " .
socket_strerror(socket_last_error()) . "\n";
} else {
echo "OK.\n";
}

echo "Attempting to connect to '$address' on port '$service_port'...";
$result = socket_connect($socket, $address, $service_port);
if ($result === false) {
echo "socket_connect() failed.\nReason: ($result) " .
socket_strerror(socket_last_error($socket)) . "\n";
} else {
echo "OK.\n";
}

$in = "HEAD / HTTP/1.1\r\n";
$in .= "Host: www.example.com\r\n";
$in .= "Connection: Close\r\n\r\n";
$out = '';

echo "Sending HTTP HEAD request...";
socket_write($socket, $in, strlen($in));
echo "OK.\n";

echo "Reading response:\n\n";
while ($out = socket_read($socket, 2048)) {
echo $out;
}

echo "Closing socket...";
socket_close($socket);
echo "OK.\n\n";
?>
0

По вопросам рекламы [email protected]