Intereting Posts
Как добавить рейтинг в список сортировки в Magento 1.7 Система кармы / репутации Как создать уникальные переменные URL, которые соответствуют записи db? Использование meteor.js с php-сервером Проблемы с особыми символами MySQL PHP-массив экспорта для json для углового приложения Просмотр хранилища фильтров на основе группы клиентов в Magento Нажав на ссылку, вы увидите ее в Разном Div на той же странице Google app-engine – загруженные файлы не являются общедоступными в облачном хранилище Google ошибка в базе данных сеанса zend для php7 Как использовать подготовленные заявления в Zend Framework APNS + PHP "stream_socket_client (): Не удалось включить криптографию" Что мне делать с Kohana 3, чтобы сделать дефисы маршрута действия в знак подчеркивания? Magento SOAP API – исключение PHP для вызова метода входа: «похоже, что у нас нет XML-документа» php imap – получить тело и сделать простой текст

Отправка сообщений с PHP на Node.js

Как отправлять сообщения с php на node.js? У меня есть сервер linux, на котором запущены php и node.js.

Когда пользователь завершает транзакцию (через php), я бы хотел отправить сообщение с php на node.js. Затем узел обновит клиент через соединение сокета.

Каким образом можно отправить небольшой объем данных с php на node.js, не нарушая производительность node.js?

Related of "Отправка сообщений с PHP на Node.js"

Предположение, похоже, заключается в том, чтобы разговаривать с узлом через HTTP-интерфейс, как это делает любой другой клиент. Вы можете поговорить с узлом через HTTP, используя cURL в php

См. http://groups.google.com/group/socket_io/browse_thread/thread/74a76896d2b72ccc/216933a076ac2595?pli=1

В частности, см. Этот пост от Мэтта Парди

Я столкнулся с аналогичной проблемой, желая информировать пользователей о новой заметке, добавленной к ошибке, и подобных уведомлениях, которые действительно могут быть эффективно отправлены только с PHP на мой сервер Node. То, что я сделал (извинения, если это получило все искаженные и неформатированные при отправке, если это произойдет, я был бы счастлив вставить код в другое место): во-первых, вам нужно будет использовать cURL из PHP. Я написал функцию для своего класса следующим образом:

function notifyNode($type, $project_id, $from_user, $data) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'http://127.0.0.1'); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:')); curl_setopt($ch, CURLOPT_PORT, 8001); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 2); curl_setopt($ch, CURLOPT_POST, true); $pf = array('f' => $type, 'pid' => $project_id, 'user_from' => $from_user, 'data' => array()); foreach($data as $k => $v) { $pf['data'][$k] = $v; } curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($pf)); curl_exec($ch); curl_close($ch); } 

Вы заметите, что я отправляю запрос cURL на тот же сервер, поскольку на нем работают PHP и NodeJS, ваш пробег может отличаться. Порт, к которому я установил этот код для подключения, – 8001 (это порт, на котором запущен мой сервер Node, и порт, к которому подключается сервер socket.io). Это отправляет HTTP-запрос POST с полем после поля. Это все довольно стандартное средство cURL.

В приложении Node у вас есть что-то вроде:

 var server = http.createServer(function(req, res) {}); server.listen(8001); var io = io.listen(server, { transports: ['websocket', 'flashsocket', 'xhr-polling'] }); ... 

хорошо, что мы будем делать здесь, расширяется на части http.createServer, чтобы прослушивать соединения, поступающие с нашего локального хоста («127.0.0.1»). Затем создается код createServer:

 var server = http.createServer(function(req, res) { // Check for notices from PHP if(res.socket.remoteAddress == '127.0.0.1') { if(req.method == 'POST') { // The server is trying to send us an activity message var form = new formidable.IncomingForm(); form.parse(req, function(err, fields, files) { res.writeHead(200, [[ "Content-Type", "text/plain"] , ["Content-Length", 0] ]); res.write(''); res.end(); //sys.puts(sys.inspect({fields: fields}, true, 4)); handleServerNotice(fields); }); } } }); 

Оттуда вы можете реализовать свою функцию handleServerNotice.

 function handleServerNotice(data) { ... } 

и т. д. Я не тестировал это некоторое время, и на самом деле этот блок кода был прокомментирован на моем узловом сервере, поэтому я надеюсь, что то, что я вставил здесь, работает – в целом эта концепция доказана, и я думаю, что это будет работа для вас. Во всяком случае, просто хотел убедиться, что вы знали, что прошло несколько месяцев, поэтому я не совсем понимаю, почему я прокомментировал это. Код, который я написал, занял немного исследований – например, настройка заголовка «Ожидание:» в cURL – и я был очень взволнован, когда он наконец-то работал. Дайте мне знать, если вам нужна дополнительная помощь.

Лучший,

Мэтт Парди

Немного поздно, но вы можете общаться с вашим клиентом узла, используя механизм Redis Pub / Sub очень простым и эффективным способом. Все, что вам нужно сделать, это установить redis на свой сервер.

На стороне php инициализируйте Redis, затем опубликуйте сообщение

 $purchase_info = json_encode(array('user_id' =>$user_id, 'purchase_information'=>array('item'=>'book','price'=>'2$')); $this->redis->publish('transaction_completed', $purchase_info); 

На стороне node.js

 var redis = require('redis'); var purchase_listener = redis.createClient(); purchase_listener.subscribe('transaction_completed'); purchase_listener.on('message', function(channel, message){ var purchase_data = JSON.parse(message); user_id = purchase_data.user_id; purchase_info = purchase_data.purchase_information; // Process the data // And send confirmation to your client via a socket connection }) 

Является ли это масштабируемым? (В ответ на @ mohan-singh)

Говоря о масштабируемости, вам нужно подумать о архитектуре вашей инфраструктуры и ваших конкретных потребностях, но вот быстрый ответ: я использовал вариант этого механизма в приложении с высоким трафиком в реальном времени без проблем, но вот что вы должны быть осторожны :

  1. Redis PUB / SUB не является системой очередей, это означает, что если ваш узел обрабатывает все сообщения, которые были отправлены WHILE, он будет потерян.

  2. Если у вас более одного подписчика издателя, все они получат одно и то же сообщение и обработают его, будьте осторожны, если у вас есть более чем процесс узла, который прослушивает один и тот же redis db, обрабатывающий вашу логику в реальном времени (есть простые способы обойти это, хотя)

Приятная вещь в этой системе заключается в том, что вам не нужно добавлять что-либо к существующей инфраструктуре, и ее можно начать немедленно, она очень быстрая и ведет себя точно так же, как HTTP-сервер.

Вот ваши альтернативы для более масштабируемых параметров:

  1. Используя сервер собственной очереди быстрого обмена сообщениями (ActiveMQ, RabbitMQ, beanstalkd …) для обработки вашей логики обмена сообщениями между php и узлом, они имеют тенденцию быть быстрыми, но по мере увеличения нагрузки вы теряете немного производительности и должны поддерживать / масштабировать серверы обмена сообщениями и заботиться о дублировании в разных регионах, что нелегко и приятно (в зависимости от того, что вам нравится делать).
  2. Использование сервера очереди размещенных сообщений (IronMQ, SQS …) Некоторые из них (IronMQ) довольно быстр и будут полезны для вашего варианта использования, но вносят некоторую (второстепенную) сложность в вашу кодовую базу.
  3. Создание очереди сообщений с Redis с кластерными серверами узлов: https://davidmarquis.wordpress.com/2013/01/03/reliable-delivery-message-queues-with-redis/
  4. Использование HTTP внутри VPN для связи с узловыми серверами. После того, как вы увидите трафик, вам нужно будет только балансировать нагрузки на ваших серверах узлов и добавить столько серверов без учета состояния, сколько вам нужно, и отправлять сообщения POST на этот балансировщик нагрузки.

Точка этого длинного редактирования заключается в том, что нет такой вещи, как волшебное масштабируемое решение, вам нужно взвесить ваши варианты и посмотреть, какой из них лучше всего подходит для вашего случая использования. На мой взгляд, если вы сейчас начинаете строить свою первую итерацию, выберите любой вариант, с которым вам удобно, напишите очень чистый код, и когда вы начнете масштабирование, это будет очень легко изменить, вот что я сделал 🙂

Шаг 1. Получить PHP-эмиттер: https://github.com/rase-/socket.io-php-emitter

 $redis = new \Redis(); // Using the Redis extension provided client $redis->connect('127.0.0.1', '6379'); $emitter = new SocketIO\Emitter($redis); $emitter->emit('new question', '<b>h<br/>tml</b>'); 

добавьте это в свой index.js:

 var redis = require('socket.io-redis'); io.adapter(redis({ host: 'localhost', port: 6379 })); io.on('connection', function(socket){ socket.on('new question', function(msg) { io.emit('new question', msg); }); }); 

добавьте что-то подобное в ваш index.html

 socket.on('new question', function(msg) { $('body').append( msg ); }); 

Я нашел, что такая проблема может быть решена просто с помощью Express Framework. Предположим, что php отправляет json-сообщение на сервер узлов, и сервер отвечает с помощью ok.

В app.js

 var app = require('express')(); var http = require('http').Server(app); var io = require('socket.io')(http); var bodyParser = require('body-parser') app.use(bodyParser.json()); app.post('/phpcallback', function(req, res) { var content = req.body; console.log('message received from php: ' + content.msg); //to-do: forward the message to the connected nodes. res.end('ok'); }); http.listen(8080, function(){ var addr = http.address(); console.log('app listening on ' + addr.address + ':' + addr.port); }); 

В test.php

 <?php $data = array("name" => "Robot", "msg" => "Hi guys, I'm a PHP bot !"); $data_string = json_encode($data); $ch = curl_init('http://localhost:8080/phpcallback'); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, array( 'Content-Type: application/json', 'Content-Length: ' . strlen($data_string)) ); echo curl_exec($ch)."\n"; curl_close($ch); ?> 

Здесь у нас также есть более подробный пример, где php-скрипт может отправить сообщение пользователям определенной комнаты чата.

https://github.com/lteu/chat


Мое личное впечатление о подходе Редиса: громоздко. Вам нужно запустить Apache, nodeJS и Redis, три сервера вместе. Механизм PubSub сильно отличается от источника socket.io, поэтому вам нужно убедиться, что он совместим с вашим существующим кодом.

Мы делаем это, используя очередь сообщений. Существует множество решений, таких как radis ( https://github.com/mranney/node_redis ) или 0mq ( http://zeromq.org/ ). Он позволяет отправлять сообщения подписчикам (например, от php до nodejs).