2015-05-26 14 views
6

Tôi có một máy chủ web phục vụ khách hàng với một luồng octet trên cổng 20000 (nó thực sự là một máy chủ socket.io được lưu trữ với node.js). Điều này đang chạy trên một tài khoản lưu trữ được chia sẻ với một máy chủ Apache thông thường chạy trên cổng 80 (điều này không thể được tắt, do đó máy chủ socket.io là trên cổng 20000). Do bức tường lửa và như vậy, tôi không thể mong đợi người dùng có thể kết nối với cổng 20000 (hoặc bất kỳ khác hơn 80). Vì vậy, làm thế nào tôi có thể phục vụ khách hàng với luồng octet được tạo ra bởi máy chủ socket.io từ máy chủ Apache (giống như một proxy ngược)? Thật không may tôi không thể sử dụng mod_proxy trên máy chủ Apache của tôi cho các hạn chế của kế hoạch lưu trữ của tôi. Tôi đã nghĩ rằng tôi có thể làm điều này với một trang PHP mở ra một ổ cắm bằng cách nào đó.Chuyển hướng một dòng octet trong Apache bằng cách sử dụng PHP hoặc Django

Cập nhật: Tôi cũng đã cài đặt Django cho Python 3 trên máy chủ có thể hữu ích. Xin lưu ý rằng proxy không thể đơn giản yêu cầu trang đích và phân phát lại cho khách hàng vì dữ liệu phải được chuyển trong thời gian thực.

+0

Django không chạy một mình nó vẫn cần một máy chủ web (Apache?) Vấn đề với apache là nó ngắt kết nối nếu trang mất quá nhiều thời gian để "tải". Nếu tường lửa của bạn chặn các kết nối tới tất cả các cổng ngoại trừ các dịch vụ đang chạy (apache/ssh/...), tôi nghĩ bạn đã hết may mắn. Nếu các cổng khác mở, bạn có thể viết dịch vụ nhận yêu cầu, kết nối với máy chủ phát trực tuyến và phục vụ dữ liệu – Ramast

Trả lời

2

Re "nó không thể đơn giản phục vụ trang đích" ... điều này không đúng vì đây là tất cả proxy HTTP. Hầu hết các giao thức proxy sử dụng một ổ cắm (so với một tập tin hoặc đường ống) và chỉ cần sao chép dữ liệu từ ổ cắm vào ổ cắm. Proxy HTTP thực hiện tương tự, ngoại trừ mọi yêu cầu HTTP yêu cầu bắt tay, vì vậy proxy sẽ yêu cầu một vài gói dữ liệu qua lại trước khi đạt đến tải trọng. Bạn có thể tạo một HTTP GET proxy rất dễ dàng trong django. Một proxy POST sẽ cần thêm footwork.

Tôi không quen với Socket.IO, nhưng khi nghiên cứu ... how does socket.io work? ... có vẻ như nó chỉ sử dụng các tính năng HTTP "cũ" và chạy mọi thứ như REST. REST được đóng gói như một vận chuyển bên trong một ổ cắm liên tục.

Nếu bạn đang tìm kiếm một proxy cấp TCP hoặc IP trong Django, nó sẽ không xảy ra. Máy chủ apache của bạn, và sau đó WSGI/CGI/bất cứ thứ gì đóng socket TCP khỏi bạn. Cách duy nhất bạn sẽ có thể truy cập nó là có đủ quyền cho các phần của máy chủ.

Đây là những gì tôi muốn làm ... Trong django, hãy tạo một mẫu url chụp ổ cắm.io api và có kết nối với chế độ xem thực hiện như sau (mã giả chưa được kiểm tra):

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 

Hy vọng điều này sẽ hữu ích. Tôi không có một dòng octet có sẵn để xin lỗi vì không thử nghiệm.

0

Dường như có thể không phải là không thể. Tôi đã không thực hiện nó trước nhưng biết cách để làm nhưng một lần nữa tôi không biết tác động của Firewall trên cổng mở và đóng cửa. Ý tưởng cơ bản về việc làm là:

Yêu cầu bạn từ cổng 80 để thực hiện mọi việc và phản hồi yêu cầu đó sử dụng cổng khác để giao tiếp với khách hàng. Nó sẽ trở thành một đường hầm để nhận yêu cầu từ một cảng và nhận được trả lời từ cảng khác. Chỉ có một điều để được chăm sóc đúng cách mà chấm dứt kết nối càng sớm càng tốt một khi mục đích là giải quyết, trừ khi nó sẽ tạo ra bộ nhớ tải trên máy chủ.

Với ví dụ bên dưới, bạn có thể thực hiện những điều trên nhưng đề nghị bạn sử dụng chúng một cách thận trọng và sau khi kiểm tra thích hợp.

ref: Programming with Sockets through PHP

Ví dụ này hiển thị một máy chủ trò chuyện đơn giản. Thay đổi địa chỉ và các biến cổng cho phù hợp với thiết lập của bạn và thực hiện. Sau đó bạn có thể kết nối với máy chủ bằng một lệnh tương tự như: telnet 192.168.1.53 10000 (nơi địa chỉ và cổng khớp với thiết lập của bạn). Bất cứ điều gì bạn gõ sau đó sẽ được đầu ra ở phía máy chủ, và lặp lại cho bạn. Để ngắt kết nối, hãy nhập 'thoát'.

<?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

Có thể định tuyến kết nối như @Ramast nói là vô dụng đối với tôi vì cổng duy nhất tôi có thể giả định máy khách có quyền truy cập vào là cổng web (80) đã được máy chủ Apache đưa lên. Vì vậy, tôi cần một cách phục vụ khách hàng thông qua máy chủ Apache. Có lẽ WSGI sẽ có ích? –

Các vấn đề liên quan