13

Recently been reading up on Node.js and how it is a great webserver and supports sockets even. I was thinking of using it on a project of mine, but i still haven't been able to figure out to to interact from CI to node.js. There was a project done for it with Drupal and it seems to be working well however i still can't figure out how they integrated it together.

Just wondering if anyone has any experience with the idea.

http://drupal.org/project/nodejs

http://www.youtube.com/watch?v=UV8lbdJfESg

Example:

User posts a comment via AJAX Comment gets store in DB All users watching the thread gets notification

now th part where after its submitted the comment and the notification, how does the msg get sent to node.js

mrsrinivas
  • 34,112
  • 13
  • 125
  • 125
DregondRahl
  • 195
  • 1
  • 1
  • 8
  • Why talk between code igniter and node.js ? – Raynos Apr 13 '11 at 19:22
  • The reason I ask is because I want to have real-time notifications for my CI application, Drupal is also a PHP CMS so i was wondering how they did it, and if its possible with Ci so i can utilize it. – DregondRahl Apr 13 '11 at 19:58
  • 1
    your options are message passing over a database like redis, message passing over a TCP socket or having Node/CI poll the database for new data. – Raynos Apr 13 '11 at 20:00

4 Answers4

18

node.js is a non-blocking IO library capable of being used as a Web Server.

Code Igniter is a PHP framework.

Do you want to run a node.js Web Server beside your PHP Web Server and have them talk to each other?

I'd recommend you do one or the other. Re write your entire website in express and now.

If they must talk to each other you can easily open a TCP socket in node by using net.

var net = require('net');

var server = net.createServer(function (socket) {
  socket.write("Echo server\r\n");
  socket.pipe(socket);
})

server.listen(8124, "127.0.0.1");

Then just use fsockopen in PHP to connect to node over a TCP socket.

Edit:

The live comments is completely independant of CI. You just need to have some socket.io javascript on you CI server pages. Your pages talk to node.js over a seperate socket and never touch the PHP back end. Your socket.io will push data to all your clients and the pages will render new messages with javascript.

All codeigniter needs to do is insert

<script src="url/socket-io.js" />
<script src="url/myChat.js" />

Further Edit:

So you need your user to log in over your websocket. I'm not sure how they log in now but sending the same username/password hash to node.js shouldn't be too hard. Get node.js to open a connection to your database where you store users. Then store which channels / threads / chat rooms / messages a particular user is "subscriped" to in a database.

Then when node receives a message from a "channel" it just asks the database which users to push that message to, and then it pushes it.

I answered a similar question about writing a chat server using node and the video tutorial of now has a good example. You should be able to turn "multiple rooms chatting" into "multiple thread commenting" pretty easily.

Further Further Edit

Don't post to the URL comment/add/ when you click add. Don't use ajax. Instead use socket.io.

So something like:

// on the client side
$("#add").click(function() {
    socket.send("add" + user.toJSON());
});

socket.on("message", function(m) {
    if (/^new/.test(m)) {
         var post = m.substring(3);
         $("#comments").append($("<div></div>").text(post));
    }
});

// on the server side
var socket = io.listen(server); 
socket.on('connection', function(client){ 
    // new client is here! 
    client.on('message', function(m){ 
        if (/^add/.test(m)) {
             client.broadcast("new"+m.substring(3));
        }
    }); 
}); 

So simply the client sends a "add comment" message when you click add. The server listens for the add message and broadcasts the message to all other clients. These clients are already listening for the new message, and new appends a comment.

Community
  • 1
  • 1
Raynos
  • 166,823
  • 56
  • 351
  • 396
  • What would be the overhead or disadvantages of have a TCP socket between node.js and PHP and how would it handle 1000s of requests? has their been any other implementation of this idea? Thanks, – DregondRahl Apr 13 '11 at 20:04
  • @DregondRahl see edit. Don't talk to your PHP. Launch your comments as a seperate node.js based service. – Raynos Apr 13 '11 at 20:10
  • @Raynos the idea could work, but some messages are like private messages too, for example, if a user is subscribed to a post and gets an that post gets updated on that that user should be notified. Along with that what about security of using node.js for database inserts? sorry for the dumb questions, i'm decent with PHP but trying out node.js has left me with a lot of questions one how it could communicate with PHP easily. – DregondRahl Apr 13 '11 at 20:19
  • @DregondRahl - Be aware that using any WebSocket functionality (such as socket-io) may be limiting to your users as it isn't designed with the lowest common denominator in mind (only works in browsers that support it, which isn't heavy at the moment). Otherwise, this method really is awesome :) – Demian Brecht Apr 13 '11 at 20:31
  • @Demian Brecht socket-io seems to be pretty crossbrowser but I am also checking other alternatives like orbited and HookBox, the problem is I can't quite figure out how to communicate with them from PHP and how to specify which users get specific messages. WebSockets are pretty insecure for now, but there are other protocols available too, just not the most efficient. – DregondRahl Apr 13 '11 at 20:39
  • @DemianBrecht socket-io has a _very_ extensive range of fall backs for legacy browsers. That's why I recommend it. WebSockets are fine in terms of security, it's all bad hype. @DregondRahl store data about your users in the database and get them to authenticate with node.js as a registered user. You'll have to duplicate your log in code. – Raynos Apr 13 '11 at 20:43
  • @Raynos is it possible to POST to node.js and it POSTs to PHP, PHP outputs a JSON string with users and the msg, and then node.js publishes it from there ? – DregondRahl Apr 13 '11 at 20:47
  • 1
    @DregondRahl your making it _FAR_ too hard. Either don't talk to the PHP or don't talk to node.js. Having PHP talk to node.js is slower then having PHP return the data itself. node.js is _not needed_ as a middle man if your going to POST to PHP. – Raynos Apr 13 '11 at 20:49
  • @Raynos Interesting (re: fall backs). I don't know much about the actual security issues surrounding WebSockets - all I know is that what I've read about support being pulled from Firefox and Opera (although I'm also not 100% sure about how up to date that data is). – Demian Brecht Apr 13 '11 at 20:58
  • @Raynos: +1 for comment regarding making it FAR too hard. – Demian Brecht Apr 13 '11 at 20:59
  • @DemianBrecht something about WebSockets taking advantage of insecure proxies where as HTTP could not abuse insecure proxies. WebSockets are fine. People just don't want to fix broken proxies. They are disabled by default in FF/OP, not supported in IE. Can be enabled in FF/OP, works in Chrome. – Raynos Apr 13 '11 at 21:01
  • @Raynos so i guess my solution is to use them separately completely. node.js will handle everything mostly. Any idea on XSS filtering with node.js for database inserts? – DregondRahl Apr 13 '11 at 21:01
  • @Raynos so, when you take the lowest common denominator (user in this case) into account, you're limiting your users to those who use Chrome. My point is that as the developer should be aware of the possible limitations that they're imposing on their users :) – Demian Brecht Apr 13 '11 at 21:06
  • @DregondRahl. ... what do you mean database inserts? Surely your sanitizing your text input right? Your appending it as a text string, you shouldn't eval any html anywhere. – Raynos Apr 13 '11 at 21:11
  • 1
    @DemianBrecht again socket-io does not use _only_ websockets. It reverts to a flash bridge, comet, long polling or simple ajax if the user does not have web sockets. It has a wide range of fallbacks when WebSockets are not available. The only difference is that it uses a WebSocket like API and does all the feature detection and browser support for you. It's future proof since in a few years all other browsers will use web sockets and you don't have to upgrade your code. – Raynos Apr 13 '11 at 21:12
  • Cool. +1 :). Blech.. Needed to add extra characters. – Demian Brecht Apr 13 '11 at 21:13
  • @Raynos thanks for the example code! Now when i make a comment say it contains {'id':'1', 'user':'dre', 'comment': 'foobar'} that gets posted to socket-io, then it will need to insert that to the database in node.js and return an object of users to broadcast to {'users': ['dre','ray','dan'], 'msg' : 'New Comment Added'}. Firstly doe socket support "private messaging" ? – DregondRahl Apr 13 '11 at 21:33
  • @DregondRahl yes you can `client.send` Keep a hash of clients by `uniqueId : Socket.Client Object`. Just save the `client` object in the `on("connect", ...` function then only send to the `clients` you want to send to. Read [docs](https://github.com/learnboost/socket.io-node). You can also access all currently connected clients by looking in `socket.clients` – Raynos Apr 13 '11 at 21:38
  • @Raynos thanks for all the ideas, ill try them out to get a better understanding and post back with my findings. Thanks again – DregondRahl Apr 13 '11 at 21:48
  • @DregondRahl post a new question if you need more help. This one is getting stupidly large. Leave a comment here saying you've made a new question or I might miss it. – Raynos Apr 13 '11 at 21:50
  • @Raynos: you mentioned socket.io.js insert to CI client pages, I wonder what socket.io are you talking about? because LearnBoost / Socket.IO-node is a nodejs module, it won't work with a php client page. Unless there are other Socket.io written specifically for php client page – angry kiwi Apr 19 '11 at 17:05
  • @runrunforest. socket-io has a server implementation for node.js. It also has a generic client implementation for the browser that can talk to any server that follows a set API. You can write a server-side socket-io implementation for PHP that follows the socket-io API and can talk to your socket-io client on the browser. Currently there are socket-io server implementation for node, rack, tornade, Java and GO. write your own for PHP. – Raynos Apr 19 '11 at 17:08
  • @Raynos: Ok I found the generic client socket.io on git hub, can you post the link to the API that helps build socket.io for php server ? – angry kiwi Apr 19 '11 at 17:54
  • @runrunforest It's called read the generic client and figure out what kind of HTTP server you need to set up to talk with it. I don't think it's well documented, and if it is I don't know where to find it. Reading some of the other OS server implementations might be a good start. – Raynos Apr 19 '11 at 18:20
  • Hi @Raynos, I figured out that this post is 5 years old. Any idea if the way of implementing NODE.JS to a CodeIgniter MVC has better easier ways (Ubuntu Linux Server)? – Imnotapotato May 31 '16 at 07:40
2

The way Drupal has done it, is use the Node.js plugin Socket.io. When a comment gets posted, drupal notifies the socket with the comment details, node.js then notifies the other "clients".

1

I have just found this package:

NodeigniterMVC - an MVC framework for node.js inspired by Codeigniter. It allows custom routing, chaining, and partial view rendering; built-in with helpers, libraries, and a CLI. Fully compatible with Bower.

https://www.npmjs.com/package/nodeignitermvc

So from what I understad, it's a package that runs unde NODE.JS if you haven't started you're project and want them both without getting yourself into too much trouble playing with sockets on your server - this looks ideal.

maybe this helps :)

Imnotapotato
  • 5,308
  • 13
  • 80
  • 147
1

I think in a general case of using node.js with CodeIgniter, there would be no direct communication between the two.

In the example you described above this could be accomplished using a technique call "long polling" with node.js . (http://blog.nemikor.com/2010/05/21/long-polling-in-nodejs/)

Essentially, your client side AJAX would make a request to your node.js server. This request on the node.js server would start a process that checks your DB for new comments every second (or 5 seconds, etc). When it finds a new comment, it would return it as the response to the client side JS AJAX call, and your JS would handle it from there.

This is one approach in which node.js and CodeIgniter could be combined.

NOTE: Node.js is very good for long polling because you can maintain many simultaneousness requests from one node.js server, due to the non-blocking, event loop based design of node.js

JohnWright
  • 248
  • 1
  • 7
  • 2
    Another approach is using CodeIgniter to server content and node.js to handle live chat over a WebSocket, the important thing is that node & CI share the same database. – Raynos Apr 13 '11 at 19:44
  • Yes, good point. The communication between Node.js and CodeIgniter would generally only be done through the DB. Having them communicate directly somehow just sounds nasty. – JohnWright Apr 13 '11 at 19:47
  • @JohnWright there's no reason they can't have a TCP socket open. This is a design alternative to having both talking to the database. There's no reason node can't query CI for data over TCP. – Raynos Apr 13 '11 at 20:00
  • I too can't think of how Durpal did their plugin to communicate with node.js properly without it getting messy. The Database method is a great idea, the 5 seconds delay wouldn't make it quite as real-time but i can understand the reasoning for it. What if we added Socket.IO to the mix and use Web Sockets? Thanks for the responses. – DregondRahl Apr 13 '11 at 20:00
  • @JohnWright wait, what? Ew! Don't poll the database. Use pubsub like redis or do proper message passing over TCP. You can have a database connection on redis waiting for new data because redis pushes to it. – Raynos Apr 13 '11 at 20:04
  • @Raynos, I think I see what you are saying. Are you suggesting having CodeIgniter return data (xml, json) and have node.js make HTTP requests to CodeIgniter? I'm not familiar with Redis, and I'm sure there are tools that may make the approach I described easier or not necessary. – JohnWright Apr 13 '11 at 20:13
  • @JohnWright redis allows you to `pop` from an array in the database. If the array is empty it will block until someone adds something into the array. So it's basically a socket, with a while loop continiously popping the array to get the messages, it's just not faffing with TCP. – Raynos Apr 13 '11 at 20:15
  • @Raynos so with redis it would be like: [1] you post data thru AJAX to PHP [2] PHP processes it, saves the comment to MySQL, Selects users subscribed to that post and create a JSON string with users and msg [3] PHP inserts this alert entry to redis [4] node.js finds the new data and pushes it thru the socket [5] node.js removes the alert entry from redis – DregondRahl Apr 13 '11 at 20:43
  • @DregondRahl why are you getting data posted to PHP ? Why not have PHP post data back to the client as an ajax success message. If you want to do it in _real time_ and take advantage of _node.js_ then you _MUST_ have your web browser talk to _node.js_ directly, not through PHP. The node.js socket has to work both way, you have to post data through the socket to node then process the data then push it back out of the socket. – Raynos Apr 13 '11 at 20:47
  • @Raynos Thanks for the response. So if we POST data thru node.js, if we have multiple kinds of notifications say when adding comments data is posted to /comments/add/ and if a thread is 'liked' it goes thru /threads/like/ would i need to make a separate function for each to pass thru socket-io add_comment(); thread_like(); ? would it possible to see an example of this kind? – DregondRahl Apr 13 '11 at 20:55
  • @DregondRahl socket-io is a TCP socket. use any protocol you like. You can even send raw XML over the stream. Your not posting to an URL. Your not talking to PHP. – Raynos Apr 13 '11 at 21:13