Using Node.js and Websockets in Cakephp 3.x
Node.js is a platform built on Chrome’s JavaScript runtime to make building applications in JavaScript that run on the server .Node.js is the latest technology that used for create realtime applications and with cakephp we can use to send updated data to each connected clients. The main advantage of node.js is that you don't need to refresh a webpage or create ajax requestto update users data.
Websockets And Node.js is the great combination to update data from server side to client side.
so here is the tutorial for how to use node.js and websockets in cakephp 3.x.
1. First we need to install node.js on server. you can follow this tutorial to How to Install Node.js.
2. Then you need to install Socket.io on your server.to install socket.io on your server you nedd to run this command.
sudo apt-get npm install socket.io
3. After installation of Socket.io we are ready to use node.js and websockets with cakephp .
4. so now we need to create a server.js file that will be run on server. and everytime a client request to connect with it then server.js connected with it and pass data to client.js
5. To fetch data and pass to all clients in cakephp we have to create a new controller that will perform all mysql operation and pass data in json format to server.js
6.Create a Controller in cakephp controllers folder example- YourProject/src/Controller/YourController.php
<?php
namespace App\Controller;
use App\Controller\AppController;
use Cake\Core\Configure;
use Cake\Network\Exception\NotFoundException;
use Cake\View\Exception\MissingTemplateException;
use Cake\Error\Debugger;
use Cake\Event\Event;
use Cake\ORM\Query;
use Cake\ORM\Table;
use App\Model\Entity\Role;
use Cake\ORM\TableRegistry;
use Cake\View\Helper\SessionHelper;
use Cake\Auth\DefaultPasswordHasher;
use Cake\Routing\Router;
use Cake\Datasource\ConnectionManager;
// src/Controller/UsersController.php
class YourController extends AppController
{
public function beforeFilter(Event $event)
{
parent::beforeFilter($event);
$this->loadComponent('Auth');
$this->Auth->allow(['getallmsg']);
/*
if (in_array($this->request->action, ['getallmsg'])) {
$this->eventManager()->off($this->Csrf);
}
*/
}
public function getallmsg($verifyid=null) {
$this->viewBuilder()->layout('blank');
if($verifyid!="" && $verifyid=="123456789")
{
$chattbl = TableRegistry::get("ChatHistory");
$chattbldata = $chattbl->find('all',['order'=>['ChatHistory.date_time'=>'DESC']])->limit(50)->toArray();
$chattbldata = array_reverse($chattbldata);
if(count($chattbldata) >0) {
foreach ($chattbldata as $chatkey => $chatvalue) {
$emoarrayGet = $this->getemoticonsep();
$chattxt = $this->replaceEmojiChat($emoarrayGet ,$chatvalue['message']);
$chattime = strtotime($chatvalue['date_time']);
//$chattxt = $chatvalue['message'];
$chatauthor = $chatvalue['username'];
$chatcolor = "black";
$arr[] = array("time"=>$chattime,"text"=>$chattxt,"author"=>$chatauthor,"color"=>$chatcolor);
}
echo json_encode($arr);
}
}else {
}
exit;
}
public function getemoticonsep()
{
$currencyData = TableRegistry::get('Emoticons');
$aProgramSendbacks = $currencyData->find('all');
if($aProgramSendbacks)
{
foreach ($aProgramSendbacks as $akey => $avalue) {
$arrEmoji[] = $avalue['name'];
}
}
return $arrEmoji;
}
function replaceEmojiChat($arremo,$string) {
//$webrootaddr = $this->request->webroot;
$servername = $_SERVER['SERVER_NAME'];
if($servername=="localhost") {
$webrootaddr = $this->request->webroot;
}else {
$webrootaddr ="https://www.thecoderain.blogspot.in/";
}
// $webrootaddr = "https://www.dc-ex.com/webroot/";
foreach ($arremo as $arkey => $arvalue) {
$keyvcal = ":".$arvalue;
$my_smilies[$keyvcal]='<img class="emojismile" src="'.$webrootaddr.'emoji/'.$arvalue.'.gif" alt="" />';
}
return str_replace( array_keys($my_smilies), array_values($my_smilies), $string);
}
}
7. Now we need to create server file Server.js that get data and sent to all client browser with a time interval. so in every 3 seconds server.js get data from cakephp controller and pass to clients browser.
var app = require('http').createServer(handler),
io = require('socket.io').listen(app),
fs = require('fs'),
connectionsArray = [],
POLLING_INTERVAL = 3000,
pollingTimer;
// creating the server ( localhost:8000 )
app.listen(8082);
function handler(req, res) {
}
var http = require('http');
var pollingLoop = function() {
var url = "http://localhost/dcex/your/getallmsg/123456789";
// Doing the database query
http.get(url, function(query){ var body = '';
users = []; // this array will contain the result of our db query
// setting the query listeners
query
.on('error', function(err) {
// Handle error, and 'end' event will be emitted after this as well
console.log(err);
updateSockets(err);
})
.on('data', function(chunk){
body += chunk;
})
.on('result', function(user) {
// it fills our array looping on each user row inside the db
//users.push(user);
})
.on('end', function() {
var fbResponse = JSON.parse(body);
//console.log("Got a response: ", fbResponse);
for (var ke in fbResponse) {
if (fbResponse.hasOwnProperty(ke)) {
var objc = {
time: fbResponse[ke].time,
text: fbResponse[ke].text,
author: fbResponse[ke].author,
color: fbResponse[ke].color
};
users.push(objc);
// console.log(fbResponse[ke].color);
}
}
if (connectionsArray.length) {
pollingTimer = setTimeout(pollingLoop, POLLING_INTERVAL);
updateSockets({
selldata: selldata
});
} else {
console.log('The server timer was stopped because there are no more socket connections on the app')
}
});
});
}
// creating a new websocket to keep the content updated without any AJAX request
io.sockets.on('connection', function(socket) {
console.log('Number of connections:' + connectionsArray.length);
// starting the loop only if at least there is one user connected
if (!connectionsArray.length) {
pollingLoop();
}
socket.on('disconnect', function() {
var socketIndex = connectionsArray.indexOf(socket);
console.log('socketID = %s got disconnected', socketIndex);
if (~socketIndex) {
connectionsArray.splice(socketIndex, 1);
}
});
console.log('A new socket is connected!');
connectionsArray.push(socket);
});
var updateSockets = function(data) {
// adding the time of the last update
data.time = new Date();
console.log('Pushing new data to the clients connected ( connections amount = %s ) - %s', connectionsArray.length , data.time);
// sending new data to all the sockets connected
connectionsArray.forEach(function(tmpSocket) {
tmpSocket.volatile.emit('notification', data);
});
};
console.log('Please use your browser to navigate to http://localhost:8082');
8. Now we only need to create a client.js and include it, that get data from server.js. to use websockets in client side we needx to call socket.io js library.in our example we are using cdn library of socket.io
client.js
<script src="https://cdn.socket.io/socket.io-1.4.5.js"></script>
<script>
var socket = io.connect('http://localhost:8082'); //create connection
socket.on('notification', function (data) { //console.log(data);
var usersList = "";
var userSData = "";
var userBdata = "";
$.each(data.users,function(index,user){
usersList += "<tr><td>" + user.time + "</td>\n" +
"<td>" + user.text + "</td>\n" +
"<td>" + user.author + "</td>\n" +
"</tr>\n";
}
});
$('#newtable').html(usersList);
</script>
9. Now in your view file create a table
<table>
<tr>
<th>Time</th>
<th>Text</th>
<th>Author</th>
</tr>
</thead>
<tbody id="newtable">
</tbody>
</table>
10 . Now open your server.js in console of your server and if you are on local server then open terminal and type command
$ node/server.js //node is the location where you install nodejs
Now run your nodejs and websockets application with Cakephp :)
Related Posts -
Using Node.js and websockets with cakephp 3.x
Node.js and Socket.io with cakephp
How to use Node.js with cakephp 3.x Tutorial
Very good explanation sir. Thank you for sharing
ReplyDeleteNode Js Online Training
Node Js Training in Hyderabad
Node Js Training in Ameerpet
Best Node Js Online Training in Hyderabad
It was really a nice post and I was really impressed by reading this keep updating
ReplyDeleteReact js Certfication Course
Angularjs online Training
NodeJS Online Training
Thanks for sharing such a valuable information.I am very thankful to you that you had given me this opportunity to write on this blog.
ReplyDeleteNode JS Online training
Node JS training in Hyderabad
Great post! I am actually getting ready to across this information, It's very helpful for this blog.Also great with all of the valuable information you have Keep up the good work you are doing well.
ReplyDeleteDigital Marketing Training in Chennai
Digital Marketing Course in Chennai