98

我最近一直在环顾四周,想找到一种在 nodeJS 和 PHP 之间进行通信的好方法。想法是这样的:nodeJS 仍然很新,仅使用它开发完整的应用程序可能有点棘手。此外,您可能只需要它用于您项目的一个模块,例如实时通知、聊天,......并且您想用 PHP 管理所有其他东西,因为它可能对您来说更容易(并且您可以利用现有的框架,如 CodeIgniter 或 Symfony)。

我想要一个简单的解决方案;我不想使用 cURL 或第三台服务器在 Apache 和 Node 服务器之间进行通信。我想要的是能够在客户端的简单 Javascript 中捕获来自节点的事件。

我没有找到任何完整的答案,大部分时间客户端由节点服务器运行,因此不适用于我的情况。于是我爬取了所有可能的话题,终于找到了我的答案;我将尝试分享这一点,并说明一切都清楚。

希望这可以帮助一些人!;)

4

3 回答 3

131

所以,首先,我把我的项目放在 github 上,如果你想访问完整的代码:https ://github.com/jdutheil/nodePHP

这是一个非常简单的示例项目:网络聊天。您只有一个作者和消息,当您按下发送时,它会保存在 mysql 数据库中。这个想法是发送实时更新,并进行真正的对话。;) 我们将为此使用 nodeJS。

PHP代码我就不说了,这里真的很简单,没有意思;我想向您展示的是如何集成您的 nodeJS 代码。

我使用 express 和 Socket.IO,所以请务必使用 npm 安装这些模块。然后,我们创建一个简单的 nodeJS 服务器:

var socket = require( 'socket.io' );
var express = require( 'express' );
var http = require( 'http' );

var app = express();
var server = http.createServer( app );

var io = socket.listen( server );

io.sockets.on( 'connection', function( client ) {
    console.log( "New client !" );

    client.on( 'message', function( data ) {
        console.log( 'Message received ' + data.name + ":" + data.message );

        io.sockets.emit( 'message', { name: data.name, message: data.message } );
    });
});

server.listen( 8080 );

当新用户连接时,我们注册了我们的事件回调;每次我们收到一条消息(代表一条聊天消息)时,我们都会将其广播给每个连接的用户。现在,棘手的部分:客户端!那部分花了我大部分时间,因为我不知道哪个脚本包括能够在没有 nodeServer 的情况下运行 Socket.IO 代码(因为客户端页面将由 Apache 提供)。

但是一切都已经完成了;当您使用 npm 安装 Socket.IO 模块时,可以使用脚本/node_modules/socket.io/node_modules/socket.io-client/dist/socket.io.js;我们将在 PHP 页面中包含的脚本,在我的例子中:

    <script src="js/node_modules/socket.io/node_modules/socket.io-client/dist/socket.io.js"></script>
    <script src="js/nodeClient.js"></script>

最后,我的 nodeClient.js,我们只需连接到节点服务器并等待事件更新我们的页面。;)

var socket = io.connect( 'http://localhost:8080' );

$( "#messageForm" ).submit( function() {
    var nameVal = $( "#nameInput" ).val();
    var msg = $( "#messageInput" ).val();

    socket.emit( 'message', { name: nameVal, message: msg } );

    // Ajax call for saving datas
    $.ajax({
        url: "./ajax/insertNewMessage.php",
        type: "POST",
        data: { name: nameVal, message: msg },
        success: function(data) {

        }
    });

    return false;
});

socket.on( 'message', function( data ) {
    var actualContent = $( "#messages" ).html();
    var newMsgContent = '<li> <strong>' + data.name + '</strong> : ' + data.message + '</li>';
    var content = newMsgContent + actualContent;

    $( "#messages" ).html( content );
});

我会尽快更新和改进我的代码,但我认为它已经对所有很酷的东西开放了!我真的很愿意就这些东西提供建议和评论,这是做这件事的好方法吗,.. ?

希望这可以帮助一些人!

于 2013-06-20T09:11:46.990 回答
2

我有另一个对我来说效果很好的解决方案,但我希望有人评论它的有效性,因为我(还没有)有机会/时间在真实服务器上对其进行测试。

这里是 node-js 代码。我将此代码放在一个名为 nodeserver.js 的文件中:

var http = require('http');

http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/html'});

    var knall = new Object();
    knall.totten = "4 tomtar";
    knall.theArr = new Array();
    knall.theArr.push("hoppla")
    knall.theArr.push("hej")
    var strKnall = JSON.stringify(knall);

    res.end(strKnall);
}).listen(process.env.PORT);  

下面是一段简单的 php 代码,在 file_get_contents() 的帮助下调用 node-js 服务器:

$json = file_get_contents('http://localhost:3002/knall.json');
$obj = json_decode($json);

效果很好,当我加载 php 页面时,它会依次调用 nodeserver.js 页面,该页面将 knall 对象 jsonify。

我在 Windows 10 上的 iis 上运行了两个 localhost 安装,一个标准 php-server,并且 nodejs-server 与整洁的iisnode包一起使用。

“真实”服务器在 ubuntu 上运行。

我认为这是两台服务器之间通信的简洁而简单的解决方案,但也许有人对此有任何意见?

于 2016-10-19T12:08:08.250 回答
0

尝试类似的,或者您可以查看我的博客以获取有关 nodejs 的完整示例代码


在您的页面方面:

  • 加载套接字 JS

https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.js

  • 制作套接字的对象

var socket = io();

  • 使用该emit函数向节点服务器发送数据。

socket.emit('new_notification', {
message: 'message',
title: 'title',
icon: 'icon',
});

所以现在你的代码看起来像

<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.js"></script>

var socket = io(); 

$(document).ready(function($) {
  $('.rules-table').on('click', '.runRule', function(event) {
    event.preventDefault();
    /* Act on the event */
    var ruleID = $(this).parents('tr').attr('id');

    // send notification before going to post 
    socket.emit('new_notification', {
        message: 'Messge is ready to sent',
        title: title,
        icon: icon,
    });
    $.ajax({
      url: '/ajax/run-rule.php',
      type: 'POST',
      dataType: 'json',
      data: {
        ruleID: ruleID
      },
    })
    .done(function(data) {
      console.log(data);

      // send notification when post success 
      socket.emit('new_notification', {
        message: 'Messge was sent',
        title: title,
        icon: icon,
      });

    })
    .fail(function() {
      console.log("error");

      // send notification when post failed 
      socket.emit('new_notification', {
        message: 'Messge was failed',
        title: title,
        icon: icon,
      });
    })
    .always(function() {
      console.log("complete");
    });

  });
});

现在在节点服务器端为您的请求制作处理程序以获取您的请求并向所有连接的设备/浏览器(server.js)发送消息

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

app.get('/', function(req, res) {
   res.sendfile('index.html');
});


io.on('connection', function (socket) {
  socket.on( 'new_notification', function( data ) {
    console.log(data.title,data.message);

    // Now Emit this message to all connected devices
    io.sockets.emit( 'show_notification', { 
      title: data.title, 
      message: data.message, 
      icon: data.icon, 
    });
  });
});

http.listen(3000, function() {
   console.log('listening on localhost:3000');
});

现在客户端/浏览器/客户端制作一个接收器来接收来自节点服务器的套接字消息

<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.js"></script>   

var socket = io();

/**
 * Set Default Socket For Show Notification
 * @param {type} data
 * @returns {undefined}
 */
socket.on('show_notification', function (data) {
    showDesktopNotification(data.title, data.message, data.icon);
});
/**
 * Set Notification Request
 * @type type
 */
function setNotification() {
    showDesktopNotification('Lokesh', 'Desktop Notification..!', '/index.jpeg');
    sendNodeNotification('Lokesh', 'Browser Notification..!', '/index.jpeg');
}
/**
 * Check Browser Notification Permission
 * @type window.Notification|Window.Notification|window.webkitNotification|Window.webkitNotification|Window.mozNotification|window.mozNotification
 */
var Notification = window.Notification || window.mozNotification || window.webkitNotification;
Notification.requestPermission(function (permission) {
});
/**
 * Request Browser Notification Permission 
 * @type Arguments
 */
function requestNotificationPermissions() {
    if (Notification.permission !== 'denied') {
        Notification.requestPermission(function (permission) {
        });
    }
}
/**
 * Show Desktop Notification If Notification Allow
 * @param {type} title
 * @param {type} message
 * @param {type} icon
 * @returns {undefined}
 */
function showDesktopNotification(message, body, icon, sound, timeout) {
    if (!timeout) {
        timeout = 4000;
    }
    requestNotificationPermissions();
    var instance = new Notification(
            message, {
                body: body,
                icon: icon,
                sound: sound
            }
    );
    instance.onclick = function () {
        // Something to do
    };
    instance.onerror = function () {
        // Something to do
    };
    instance.onshow = function () {
        // Something to do
    };
    instance.onclose = function () {
        // Something to do
    };
    if (sound)
    {
        instance.sound;
    }
    setTimeout(instance.close.bind(instance), timeout);
    return false;
}
于 2019-05-30T08:15:30.913 回答