如何集成 nodeJS + Socket.IO 和 PHP?

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

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

我没有找到任何答案,在完整的情况下,大部分时间客户端是由节点服务器运行的,因此不适用于我的情况。所以我搜索了所有可能的主题,最终找到了我的答案; 我会试着分享这个,并且找到一个一切都清楚的点。

希望这能帮到一些人! ;)

86970 次浏览

So, to begin with, I put my project on github, if you want access to the full code: https://github.com/jdutheil/nodePHP

It is a very simple example project: a web chat. You just have an author and message, and when you press send it is saved in a mysql database. The idea is to send real time updates, and have a real conversation. ;) We'll use nodeJS for that.

I won't talk about PHP code, it is really simple and not interesting here; what I want to show you is how to integrate your nodeJS code.

I use express and Socket.IO, so be sure to install those modules with npm. Then, we create a simple nodeJS server:

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 );

We registered our events callback when a new user is connected ; every time we receive a message (represents a chat message), we broadcast it to every users connected. Now, the tricky part: client-side! That the part that took me most of the time, because I didn't know which script include to be able to run Socket.IO code without the nodeServer (because client page will be served by Apache).

But everything is already done; when you install Socket.IO module with npm, a script is available in /node_modules/socket.io/node_modules/socket.io-client/dist/socket.io.js; that the script we will include in our PHP page, in my case:

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

And to finish, my nodeClient.js, where we simply connect to the node server and wait for event to update our page. ;)

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 );
});

I'll try to update and improve my code as soon as possible, but I think it already open to all of cool things! I am really open for advice and reviews on this stuff, is it the good way to do it, .. ?

Hope this can help some people!

I have another solution that works quite well for me, but I would like someone to comment about how effective it is, as I have not (yet) had the opportunity/time to test it on the real server.

Here goes the node-js code. I put this code in a file called 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);

And here is the simple piece of code in php, calling the node-js server with the help of file_get_contents():

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

Works great, when I load the php-page, it in turn calls the nodeserver.js page, which jsonify the knall-object.

I have two localhost-installations running on iis on windows 10, one standard php-server, and the nodejs-server works with the neat iisnode package.

The 'real' server is run on ubuntu.

I think this is a neat and easy solution for communication between two servers, but maybe someone has any comments about it?

Try similar or you can check my blog for complete sample code on nodejs


On your page side:

  • Load Socket JS

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

  • Make object of the socket

var socket = io();

  • Use the emit function to send data to nodeserver.

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

So now your code will be look like

<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");
});


});
});

Now on Node server side make handler for your request to get your request and send a message to all connected devices/browsers(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');
});

Now the client/browser/client side make a receiver to receive socket message from node server

<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;
}