ActiveState имеют Набор Tcl Dev, который должен помочь Вам сделать это.
Функции сокетов PHP могут быть самым простым подходом. Socket_create будет обрабатывать соединения IPv4, IPv6 и UNIX. Быстрый пример
$socket = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
$address = '127.0.0.1';
$port = 80;
socket_connect($socket,$address,$port);
// Sending data
socket_write('Your API commands here');
// Reading data
while ($buffer = socket_read($socket,1024,PHP_NORMAL_READ)) {
if(trim($buffer) == 'END') {
break;
}
}
socket_close($socket);
Дополнительные примеры на php.net: Примеры сокетов
Nginx, настроенный как обратный прокси может сделать это легко :
http {
upstream remoteserver {
# here you add your remote server's IPs or hostnames
server 54.175.222.246; # for example here we use HTTPBin's address
keepalive 10; # maintain a maximum of 10 open connections
}
server {
listen 80;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # passing the client's IP to the remote server, on a local machine it doesn't do much though
proxy_set_header Host $http_host; # passing the Host header as requested by the client, otherwise this will default to the pool's name, "remoteserver" in this case
proxy_pass http://remoteserver; # sends the request off to the pool defined above
}
}
}
Теперь вы можете направить ваши скрипты на локальный сервер, а не на удаленный, вот демо-версия с curl
:
$ curl http://localhost/get -H "Host: host header is passed normally"
{
"args": {},
"headers": {
"Accept": "*/*",
"Host": "host header is passed normally",
"User-Agent": "curl/7.29.0"
},
"origin": "127.0.0.1, 1.2.3.4",
"url": "http://host header is passed normally/get"
}
Как вы можете видеть, даже заголовок Host передается как есть.
Или вы можете сделать переход незаметным, сделав так, чтобы имя удаленного хоста указывало на вашу локальную машину, либо в /etc/hosts
, либо в конфигурации DNS resolver. В этом случае, убедитесь, что в определении пула в конфигурации Nginx вместо имен хостов используются только IP адреса, иначе прокси также зациклится обратно на себя, что может привести к небольшому сбою.
Как только файл хостов был изменен соответствующим образом, проксирование является бесшовным :
$ curl http://httpbin.org/get -v
* About to connect() to httpbin.org port 80 (#0)
* Trying 127.0.0.1...
* Connected to httpbin.org (127.0.0.1) port 80 (#0)
> GET /get HTTP/1.1
> User-Agent: curl/7.29.0
> Host: httpbin.org
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.6.2
< Date: Sun, 15 Mar 2015 00:41:54 GMT
< Content-Type: application/json
< Content-Length: 198
< Connection: keep-alive
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Credentials: true
<
{
"args": {},
"headers": {
"Accept": "*/*",
"Host": "httpbin.org",
"User-Agent": "curl/7.29.0"
},
"origin": "127.0.0.1, 1.2.3.4",
"url": "http://httpbin.org/get"
}
Как вы видите, наш локальный сервер ведет себя так же, как и удаленный, и любая программа, пытающаяся получить доступ к имени удаленного хоста, на самом деле будет подключаться к нашему локальному серверу.
Обратите внимание, что это может потребовать дополнительной настройки для хостов, основанных на HTTPS.
.Возможно, вы захотите написать php-скрипт, который будет запущен из командной строки и демонизирует, откроет хэндл скручивания и будет повторно использовать его для каждого последующего запроса, таким образом, используя функцию keep-alive. Этот сценарий должен предоставлять API, использующий очереди сообщений (обратите внимание на beanstalkd / rabbitmq). Как только в очереди появится новое сообщение, скрипт должен сделать запрос к внешнему API и вставить результат обратно в очередь сообщений. Альтернативный вариант - предоставление API с использованием сокетов (но это может быть очень хитро, так как это должно быть многопоточным, многопоточность в PHP может быть достигнута с помощью fork, и я не уверен, как поведет себя curl handle, если вы попробуете использовать его в нескольких подпроцессах за раз). Также может произойти падение производительности при использовании этого метода, поэтому, если у вас много пользователей, вам, вероятно, следует создать несколько демонов, которые будут запускаться одновременно.
.