I have a few questions regarding using socket IO with PHP and such, I am new to nodejs/socket io so I know very little, I have just started using it over the past few days and I'm getting to the point where I will be implementing this onto my website (as of now I have just been building little test examples).
Question: Currently I have to add the port to my localhost in order to view it and have it work, obviously I can't have this when it's a live website, and I also can't do this when I use php pages (just have been doing examples with html) If I'm using port 4000 for my socket io server I have to go to: localhost:4000, however I need to be able to go to: localhost:8888/mysitefolder (8888 is the port for my MAMP, for php and everything) I have seen in questions where people have solved this but I have been unable to get it to work for my self.
Here is my code:
chat.js
var app = require('express').createServer(),
io = require('socket.io').listen(app);
app.listen(4000);
var users = [];
app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});
io.sockets.on('connection', function (socket) {
socket.emit('connected');
socket.on('userID', function (userID) {
users.push(userID);
});
socket.on('message', function (message) {
socket.broadcast.emit('message-response', { data: message});
});
});
index.html
<title>Testing</title>
<script src="/socket.io/socket.io.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script>
function mktime(){
var newDate = new Date;
return newDate.getTime();
}
function appendMessage(data)
{
$("body").append(data+"<br />");
}
var socket = io.connect('http://localhost:4000');
socket.on('connected', function () {
//select id from database in real environment
socket.emit("userID", mktime());
});
socket.on('message-response', function (message) {
appendMessage(message.data);
});
$(document).ready(function(){
$('#input').keypress(function(event) {
if (event.keyCode != 13) return;
var msg = $("#input").val();
if (msg) {
socket.emit('message', msg );
appendMessage(msg);
$("#input").val('').focus();
}
});
});
</script>
<body>
<input type="text" id="input"><br>
</body>
I think you mean that you do not want to hard code a port or url in the client? Is that right?
In socket.io 0.8.7, you don't need to provide it. You can just use the following and it will be autodetected
var socket = io.connect();
Related
I want to connect frontend using PHP file with socket.io
How can I convert this js file code into PHP?
I want to implement this functionality in Laravel but right now I have tested this in PHP
I have connected with the help of NODE JS and it working fine.
HTML file:
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script>
<script>
(function () {
const onMessage = (data) => {
console.log(data);
};
var connectToServer = function () {
var socket = io.connect('http://localhost:8000');
socket.on('message-name', onMessage);
};
connectToServer();
})();
</script>
</head>
<body>
</body>
</html>
Js file :
var amqp = require('amqp'),
express = require('express'),
http = require('http'),
app = express();
var server = http.createServer(app);
var io = require('socket.io').listen(server),
rabbitMq = amqp.createConnection({url: "amqp://***:***#x.x.x.x:1234//"});
// add this for better debugging
rabbitMq.on('error', function(e) {
console.log("Error from amqp: ", e.message);
});
// Wait for connection to become established.
rabbitMq.on('ready', function () {
rabbitMq.queue('1', {passive : true} , function(queue) {
queue.bind('#');
queue.subscribe(function (message) {
// Print messages to stdout
var buff = JSON.stringify(message);
var bufferData = JSON.parse(buff);
var messageData = bufferData['data']['data'];
io.sockets.on('connection', function (socket) {
socket.emit('message-name', messageData);
});
});
});
});
server.listen(8000);
I have a div section. I want to reload this section every 5 seconds. How do I do this. Here is my code:
<script>
$("#send_parent_general_chat").submit(function()
{
var rec = $("#data").val();
var msg = $("#msg").val();
var dataString = 'rec='+ rec + '&msg='+ msg;
$.ajax({
type: "POST",
url: "<?php echo base_url(); ?>" + "Client/send_general_parent_chat_msg/<?php echo $per_job->id;?>",
data: dataString,
cache: false,
success: function(result){
$('#display_general_msg').html(result);
$('#send_parent_general_chat')[0].reset(); //form reset
}
});
return false;
});
</script>
<script>
$(document).ready(function(){
setInterval(function(){
// alert("===111==");
$("#display_general_msg").load('<?php echo base_url(); ?>" + "Client/refresh_general_parent_chat_msg/<?php echo $per_job->id;?>')
}, 5000);
});
</script>
I have created one more controller for refreshing the div I have used the time interval function but it is not loading, it shows this error:
Access forbidden!
You don't have permission to access the requested object. It is either read-protected or not readable by the server.
If you think this is a server error, please contact the webmaster.
Error 403
I need to refresh only the div content not the whole page.
How do I achieve this?
You can Use :
setTimeout(function()
{
Your_Function(); //this will send request again and again;
}, 5000);
Replace Your_Function with your Function Name.
Hope this will help !!
Below is an example which will update the contents in every 5 seconds using php websockets. This is a simple example, but you can use it to modify to fit for your application needs. You don't need the timeout functions on the client side here we use server sleep
Install the Workerman socket library
composer require workerman/workerman
The client side code
<!DOCTYPE HTML>
<html>
<head>
<script type = "text/javascript">
function WebSocketTest() {
if ("WebSocket" in window) {
//alert("WebSocket is supported by your Browser!");
// Let us open a web socket
var ws = new WebSocket("ws://localhost:2346");
ws.onopen = function() {
// Web Socket is connected, send data using send()
ws.send("Message to send");
//alert("Message is sent...");
};
ws.onmessage = function (evt) {
var received_msg = evt.data;
//alert("Message is received..." + received_msg);
document.getElementById("demo").innerHTML = "Timestamp is updated every 5 sec " +received_msg;
};
ws.onclose = function() {
// websocket is closed.
alert("Connection is closed...");
};
} else {
// The browser doesn't support WebSocket
alert("WebSocket NOT supported by your Browser!");
}
}
</script>
</head>
<body>
<div id = "sse">
Run WebSocket
</div>
<div id="demo" style="font-size: 64px; color: red;"></div>
</body>
</html>
The Server side code
<?php
require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Worker;
// Create a Websocket server
$ws_worker = new Worker("websocket://0.0.0.0:2346");
// 4 processes
$ws_worker->count = 4;
// Emitted when new connection come
$ws_worker->onConnect = function($connection)
{
echo "New connection\n";
};
// Emitted when data received
$ws_worker->onMessage = function($connection, $data)
{
// Send hello $data
while(true) {
$connection->send(time());
sleep(5); //Sleep for 5 seconds to send another message.
}
};
// Emitted when connection closed
$ws_worker->onClose = function($connection)
{
echo "Connection closed\n";
};
// Run worker
Worker::runAll();
The backend service can be started with the following command from the terminal or you can autostart on boot if you want.
$php index.php start
Here index.php is our backendnd file name.
Just start the service and load the page then you can see the timestamp is updated every 5 seconds which comes from the server side. This is a working example tested on my local machine. Try and let me know if you need any other help.
The output
you can also try below one:
setInterval(function(){
loadlink() // this will run after every 5 seconds
}, 5000);
setInterval approach will be more accurate than the setTimeout approach
// or
$(function(){ // document.ready function...
setTimeout(function(){
$('form').submit();
},5000);
});
I have a node.js server running on the port 8443. Whenever I try to run the application through the browser my socket.io keeps connecting for about 20 seconds before the url turns red at the end.
Edit 3 : This is my directory structure and now with updated files
/var/www/html/nodetest/
Inside this
/node_modules
/app.js
/index.html
Node JS is installed on server.
Here is my main app.js code (as suggested in answer) :
var app = require('express')();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
var fs = require('fs');
// Run server to listen on port 8443.
server = app.listen(8443, () => {
console.log('listening on *:8443');
});
io.listen(server);
io.sockets.on('connection', function(socket) {
socket.emit('message', 'this is the message emitted by server');
});
app.get('/', function(req, res){
fs.readFile(__dirname + 'index.html', function(error, data) {
res.writeHead(200);
res.end(data);
});
});
And this is my client browser side code:
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.5.1
/socket.io.min.js"></script>
<script type="text/javascript">
var websocket;
function onload() {
websocket = io.connect();
websocket.on('message',function(data) {
console.log('Received a message from the server!',data);
});
};
</script>
</head>
<body onload="onload()">
<div id="divId"></div>
</body>
</html>
Here is an image of the error
Now it shows 404 Error
I've modified the code as per your need. The code is working as it is showing message emitted by server after loading in browser's console as in the below image.
Server.js:
let express = require('express')
let app = express();
let http = require('http').Server(app);
let io = require('socket.io')(http);
let port = 8443;
var fs = require('fs');
var path = require('path');
app.get('/', function (req, res) {
fs.readFile(path.join(__dirname, 'index.html'), function (error, data) {
res.writeHead(200);
res.end(data);
});
});
// Run server to listen on port 8443.
http.listen(port, function () {
console.log(`listning on ${port}`);
});
io.on('connection', function (socket) {
socket.emit('message', 'this is the message emitted by server');
socket.on('disconnect', function () {
console.log('Client disconnected');
});
});
index.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.5.1/socket.io.min.js"></script>
<script type="text/javascript">
var websocket;
function onload() {
websocket = io().connect();
websocket.on('message', function (data) {
console.log('Received a message from the server!', data);
});
};
</script>
</head>
<body onload="onload();">
</body>
</html>
The out put is as below:
You are doing this in a manner I haven't seen yet. Here is an example that is working. The main difference is my webserver returns the file that I am connecting with the socket.
EDIT: I updated this to use your webserver. I modified it to make it make it server the index.html file.
Webserver:
var app = require('express')();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
var fs = require('fs');
// Run server to listen on port 8000.
server = app.listen(8447, () => {
console.log('listening on *:8447');
});
io.listen(server);
io.sockets.on('connection', function(socket) {
socket.emit('message', 'this is the message emitted by server');
});
app.get('/', function(req, res){
fs.readFile(__dirname + '/index.html', function(error, data) {
res.writeHead(200);
res.end(data);
});
});
index.html
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.5.1/socket.io.min.js"></script>
<script type="text/javascript">
var websocket;
function onload() {
websocket = io.connect();
websocket.on('connect',function() {
console.log('Client has connected to the server!');
});
websocket.on('message',function(data) {
console.log('Received a message from the server!',data);
});
websocket.on('disconnect',function() {
console.log('The client has disconnected!');
});
};
</script>
</head>
<body onload="onload()">
<div id="divId"></div>
</body>
</html>
You are creating two separate servers and only starting one of them so your socket.io server is never started.
Change this:
var app = require('express')();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
// Run server to listen on port 8000.
server = app.listen(8447, () => {
console.log('listening on *:8447');
});
to this:
var app = require('express')();
// Run server to listen on port 8000.
var server = app.listen(8447, () => {
console.log('listening on *:8447');
});
var io = require('socket.io')(server);
app.listen() creates its own server so you don't want to use both it and http.createServer().
Here's the code for app.listen() so you can see how it works:
app.listen = function(){
var server = http.createServer(this);
return server.listen.apply(server, arguments);
};
So, you can see that the server you created with http.createServer() and then bound to socket.io was never started with .listen().
You make a simple mistake. In your html file change socket.io library file source https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.5.1/socket.io.min.js to socket.io cdn sorce which is https://cdn.socket.io/socket.io-1.4.5.js.
After that run restart you app.
if yo getting 404 again, then in you html replace websocket = io.connect(); to websocket = io.connect(your_server_domain_or_host_name:nodejs_server_running_port);
I've heard that nodejs is the best choice for creating real-time chat application. So I decide to try one.
//on server side
//create nodejs server
var http = require('http');
var chatApp = http.createServer(function (request, response) {
//create an html chat form listened by this nodejs server
response.writeHead(200, {'Content-Type': 'text/html'});
response.write('<script src="http://localhost/nodejs/app/socket.io.js"></script><script src="http://localhost/nodejs/app/chat.client.js"></script><input type="text" id="message_input"><div id="chatlog"></div>');
response.end();
}).listen(8000);
//create websocket protocol via socket.io
var io = require('socket.io').listen(chatApp);
//send data to client
io.sockets.on('connection', function(socket) {
socket.on('message_to_server', function(data) {
io.sockets.emit("message_to_client",{ message: data["message"] });
});
});
//on client side
//get data from server response
var socketio = io.connect();
socketio.on("message_to_client", function(data) {
document.getElementById("chatlog").innerHTML = ("<hr/>" +
data['message'] + document.getElementById("chatlog").innerHTML);
});
//submit and send data to server via enter key
document.onkeydown = function(e){
var keyCode = (window.event) ? e.which : e.keyCode;
if(keyCode == 13){
var msg = document.getElementById("message_input").value;
socketio.emit("message_to_server", { message : msg});
document.getElementById("message_input").value = '';
}
};
Everything seems ok but php webapp intergration. How could I make it work as a part of a php web page?
As mentioned in my original comment, you can let your PHP application continue doing what it has been doing all along and just use NodeJS for handling web socket connections (via the socket.io) library. Here is an example of a simplified structure you could use:
Your chat.php page or Chat controller:
<?php
// Handle /chat route
// Perform any authentication with your database
// Render template
?>
<!-- The following HTML is rendered -->
<html>
<head>
...
<script src="http://localhost/nodejs/app/socket.io.js"></script>
<script src="http://localhost/nodejs/app/chat.client.js"></script>
</head>
<body>
...
<input type="text" id="message_input">
<div id="chatlog"></div>
...
<script>
var socketio = io.connect('http://localhost:8080');
socketio.on("message_to_client", function(data) {
document.getElementById("chatlog").innerHTML = ("<hr/>" +
data['message'] + document.getElementById("chatlog").innerHTML);
});
//submit and send data to server via enter key
document.onkeydown = function(e){
var keyCode = (window.event) ? e.which : e.keyCode;
if(keyCode == 13){
var msg = document.getElementById("message_input").value;
socketio.emit("message_to_server", { message : msg});
document.getElementById("message_input").value = '';
}
};
</script>
</body>
</html>
Your NodeJS application would look like the following. Note the lack of regular HTTP connection handling, which we now let PHP handle:
//create websocket protocol via socket.io
var io = require('socket.io').listen(8080);
//send data to client
io.sockets.on('connection', function(socket) {
socket.on('message_to_server', function(data) {
io.sockets.emit("message_to_client",{ message: data["message"] });
});
});
And that is the base you would use. As mentioned before in my comment, it is possible to extend this to add database-backed authentication mechanisms to the NodeJS portion of the server.
I'm developing a small project where I have a web page (index.html) loading in Express.js and it sends some data to a PHP script running on a MAMP server. The PHP script processes the data and returns a JSON encoded array back to the web page and finally the Node.js server sends data to connected clients using socket.io.
I have problems with the communication with PHP using jQuery Ajax. I send the data to PHP using POST and I know PHP receives that data but I don't know how to catch the response from PHP to know how the processing went.
I have no experience with Node.js. What can I do to make this thing work?
So far this is the code I have
Node.js - Express.js
var express = require('express')
, routes = require('./routes')
, user = require('./routes/user')
, db = require('./routes/db')
, http = require('http')
, socketio = require('socket.io')
, path = require('path');
var app = express();
app.set('port', process.env.PORT || 3000);
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser()); //Middleware
app.use('/', express.static(__dirname + '/public'));
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
app.get('/', routes.index);
app.get('/users', user.list);
var server = http.createServer(app);
server.listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
HTML Page
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Site</title>
<script src="js/jquery-2.0.3.min.js" type="text/javascript"></script>
</head>
<body>
<div id="formContainer">
<form enctype="multipart/form-data">
<input type="text" name="texto">
<button type="button" id="buttonSend">Enviar</button>
</form><br/><br/>
</div>
<script type="text/javascript">
$('#buttonSend').click(function(e){
e.preventDefault();
$.ajax({
url: 'http://localhost:8080/NodePHP/test.php',
type: 'POST',
dataType: "json",
data: {value: 1},
success: function(data){
if(data.success == true){
alert("Perfect!");
}
else{
alert("Error!");
}
},
error: function(xhr,status,error){
//alert("Error de llamada al servidor");
alert(xhr.responseText);
//$('#botonUsarFoto').css('display','block');
}
});
});
</script>
</body>
</html>
PHP Script
<?php
$number = $_POST['value'];
echo $number;
// move the image into the specified directory //
if ($number == 1) {
$data = array("success"=>"true");
echo json_encode($data);
} else {
$data = array("success"=>"false");
echo json_encode($data);
}
?>
Thanks in advance for any help
In order to make a request with Node, we'll use the http and querystring modules. Here's an example lovingly adopted from the Nodejitsu folks:
var http = require('http');
var querystring = require('querystring');
var data = querystring.stringify({
value: 1
});
var options = {
host: 'localhost',
path: '/myPHPScript',
method: 'POST'
};
callback = function(response) {
var str = '';
response.on('data', function (chunk) {
str += chunk;
});
response.on('end', function () {
console.log(str);
});
}
var req = http.request(options, callback);
req.write(data);
req.end();
Alternatively, you could use the request module, but first things first.