I am new to this, I built a standard web chat application and I see the power of nodejs, express, socket.io.
What I am trying to do is trigger events from a phone to a website, like a remote control. There is server javascript that listens to events from the client, and client javascript that triggers those events, this is how I understand it correct me if I am wrong.
I learned in the chat app I can send an object from anywhere, as long as they are connected to my server through a specific port http://my-server-ip:3000/. Basically all events are inside the index page, and the connection is index to server to index.
What I am trying to learn is how to trigger events from an external page, I've seen things like http://my-server-ip:3000/ws or something like that, the idea is to connect to a mobile interface that isn't the actual index or website itself, but this interface communicates with the node server using it as a dispatcher to trigger events on the main index page.
Basically what I have learned was index to server to index. I am not sure how I can go custom-page to server to index.
I see that in my app.js, my understanding is that the socket listens to sends which is on the client then it emits the message.
io.sockets.on('connection', function (socket) {
socket.on('sends', function (data) {
io.sockets.emit('message', data);
});
});
I tried creating a test.html that has a button on it, I tried listening to it, here is a screen shot.
Here is my client code
window.onload = function() {
var messages = [];
var socket = io.connect('http://my-server-ip:3000/');
var socketTwo = io.connect('http://my-server-ip:3000/test.html');
var field = document.getElementById("field");
var sendButton = document.getElementById("send");
var content = document.getElementById("content");
var name = document.getElementById("name");
var trigBtn = document.getElementById("trigger-btn");
socket.on('message', function (data) {
if(data.message) {
messages.push(data);
var html = '';
for(var i=0; i<messages.length; i++) {
html += '<b>' + (messages[i].username ? messages[i].username : 'Server') + ': </b>';
html += messages[i].message + '<br />';
}
content.innerHTML = html;
} else {
console.log("There is a problem:", data);
}
});
//FROM DEMO
// sendButton.onclick = sendMessage = function() {
// if(name.value == "") {
// alert("Please type your name!");
// } else {
// var text = field.value;
// socket.emit('send', { message: text, username: name.value });
// field.value = "";
// }
// };
//I include this javascript with test.html and trigger
//this button trying to emit a message to socketTwo
trigBtn.onclick = sendMessage = function() {
socketTwo.emit('send', { message: 'String test here' })
}
}
I am sure that is all wrong, but hopefully this makes sense and someone can help me trigger events from another page triggering to the index.
Here is my app.js server code
/**
* Module dependencies.
*/
var express = require('express')
, routes = require('./routes')
, http = require('http');
var app = express();
var server = app.listen(3000);
var io = require('socket.io').listen(server); // this tells socket.io to use our express server
app.configure(function(){
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.static(__dirname + '/public'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
});
app.configure('development', function(){
app.use(express.errorHandler());
});
app.get('/', routes.index);
app.get('/test.html', function(req, res) {
res.send('Hello from route handler');
});
io.sockets.on('connection', function (socket) {
socket.emit('message', { message: 'welcome to the chat' });
socket.on('send', function (data) {
io.sockets.emit('message', data);
});
});
All code posted above is just testing cookie cutter code, I am learning from scratch so the above can be totally changed, it's just there as a starter point.
This is so cool I got it to work, so my logic was correct. There were just a few things I was missing. Here it is.
I am not going to post all the server side javascript code, but here is the main logic after listening to the port etc.
// Set a route and in a very dirty fashion I included a script specific
// for this route, earlier I was using one script for both route.
// I also forgot to include the socket.io hence the error in the image above.
app.get('/test', function(req, res) {
res.send('<script src="/socket.io/socket.io.js"></script><script type="text/javascript" src="javascripts/trigger.js"></script><button id="test" class="trigger-btn">Trigger</button>');
});
// This listens to `send` which is defined in the `test` route
// Upon this action the server emits the message which
// is defined inside the index main route I want stuff displayed
io.sockets.on('connection', function (socket) {
socket.on('send', function (data) {
io.sockets.emit('message', data);
});
});
Here is what the index client,js script looks like
window.onload = function() {
var messages = [];
var socket = io.connect('http://my-server-ip:3000');
var content = document.getElementById("content");
socket.on('message', function (data) {
if(data.message) {
messages.push(data);
var html = '';
for(var i=0; i<messages.length; i++) {
html += '<b>' + (messages[i].username ? messages[i].username : 'Server') + ': </b>';
html += messages[i].message + '<br />';
}
content.innerHTML = html;
} else {
console.log("There is a problem:", data);
}
});
}
Related
Scenario:
I have a server which is accessed by multiple users. Server for ex: http://127.0.0.1:8081
It has one button and by clicking on it, it runs one selenium automated test.
I want to get a list of tests currently running by multiple users.
So for ex: if 5 users are accessing that server and clicked on that button 2 times it means that automated tests running are 10.
How can I get above count in node.js express like how many processes are running?
My server.js :
var express = require('express');
var app = express();
app.get('/', function (req, res) {
res.send(
'<form action="/server" method="POST">' +
' <input type="submit" name="server" value="Run Script" />' +
'</form>');
});
app.post('/server', function (req, res) {
var fork = require('child_process').fork;
var child = fork('./test');
res.send('Test Started....');
});
var server = app.listen(8081, function () {
var host = server.address().address
var port = server.address().port
console.log("Example app listening at http://%s:%s", host, port)
Not tested, but the following should do something like what your after.
Not sure were you wanted to access counter, so done another route /counter that echo the current counter out.
var express = require('express');
var app = express();
var counter = 0;
app.get('/', function (req, res) {
res.send(
'<form action="/server" method="POST">' +
' <input type="submit" name="server" value="Run Script" />' +
'</form>');
});
app.get('/counter', function (req, res) {
res.end("Counter = " + counter);
});
app.post('/server', function (req, res) {
var fork = require('child_process').fork;
var child = fork('./test');
counter ++;
child.on("close", function () { counter --; });
res.send('Test Started....');
});
var server = app.listen(8081, function () {
var host = server.address().address
var port = server.address().port
console.log("Example app listening at http://%s:%s", host, port)
You can maintain global count for clicked button.
global.total_tests = 0; // note this line
var express = require('express');
var app = express();
app.post('/server', function (req, res) {
var fork = require('child_process').fork;
var child = fork('./test');
res.send('Test Started....');
total_tests++; // note this line
});
I hope this help.
Thanks.
I'd recommend using ps-node as suggested in this earlier Stackoverflow post.
I'm using node.js to read data from socket on my web application (server). I receive data and make some changes on webpage (ex: change the color of polyline) but when a client after that changes connects, cannot see the changed color unless a new data is sent to server! So how client can see the previous changes which were on server?
here is my code
app.js
var http = require('http');
var express = require('express'),
app = module.exports.app = express();
var server = http.createServer(app);
var io = require('socket.io').listen(server); //pass a http.Server instance
server.listen(3000); //listen on port 80
app.use(express.static('public'));
app.get('/', function(req, res) {
res.sendFile(__dirname + '/index.html');
});
//var app = require('http').createServer(handler);
//var io = require('socket.io').listen(app);
var fs = require('fs');
var mySocket = 0;
//app.listen(3000); //Which port are we going to listen to?
function handler (req, res) {
fs.readFile(__dirname + '/index.html', //Load and display outputs to the index.html file
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
io.sockets.on('connection', function (socket) {
console.log('Webpage connected'); //Confirmation that the socket has connection to the webpage
mySocket = socket;
});
//UDP server on 41181
var dgram = require("dgram");
var server = dgram.createSocket("udp4");
server.on("message", function (msg, rinfo) {
console.log("Broadcasting Message: " + msg); //Display the message coming from the terminal to the command line for debugging
if (mySocket != 0) {
mySocket.emit('field', "" + msg);
mySocket.broadcast.emit('field', "" + msg); //Display the message from the terminal to the webpage
}
});
server.on("listening", function () {
var address = server.address(); //IPAddress of the server
console.log("UDP server listening to " + address.address + ":" + address.port);
});
server.bind(41181);
index.html
<html>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://192.168.1.14:3000');
socket.on('field', function (data) {
console.log(data);
$("#field").html(data);
switch(data)
{
case "1":
$("#path1").css("stroke", "red");
$("#progress1").css("backgroundColor", "red");
break;
}
});
</script>
<body>
<polyline id="path1" points="600,270 560,262 460,270 440,300" style="fill:none;stroke:green;stroke-width:3" />
</body>
</html>
On connection you have to emit already existing changes to socket client.
var myMessage;
io.sockets.on('connection', function (socket) {
console.log('Webpage connected'); //Confirmation that the socket has connection to the webpage
mySocket = socket;
mySocket.emit('field', "" + myMessage); // <<-- like this
server.on("message", function (msg, rinfo) {
console.log("Broadcasting Message: " + msg); //Display the message coming from the terminal to the command line for debugging
if (mySocket != 0) {
myMessage = msg;
mySocket.emit('field', "" + msg);
mySocket.broadcast.emit('field', "" + msg); //Display the message from the terminal to the webpage
}
});
});
I am trying to learn Node and build a simple chat application. It seems like everyone uses socket.io. I would like to understand how to do this on a more fundamental level using get and post.
Basically, all I want to do is have a form that takes an input and reposts it below the form for everyone to see.
This is what I have so far:
//Requirements
var express = require('express');
var app = express();
//GET
app.get('/', function (req, res) {
// res.send('Hello World!');
var response =
"<HEAD>"+
"<title>Chat</title>\n"+
"</HEAD>\n"+
"<BODY>\n"+
"<FORM action=\"/\" method=\"get\">\n" +
"<P>\n" +
"Enter a phrase: <INPUT type=\"text\" name=\"phrase\"><BR>\n" +
"<INPUT type=\"submit\" value=\"Send\">\n" +
"</P>\n" +
"</FORM>\n" +
"<P>phrase</P>\n"+
"</BODY>";
var phrase = req.query.phrase;
if(!phrase){
res.send(response);
}else{
res.send(response);
res.send(phrase);
}
});
//For testing
app.get('/test', function(req, res){
res.send('I am a robot');
console.log('told visiter I am a robot');
});
//Run the app
var server = app.listen(8080, function () {
var host = server.address().address;
var port = server.address().port;
console.log('App listening at http://%s:%s', host, port);
});
I've been trying a bunch of things, but I am pretty stumped.
Did you hear about messaging backend jxm.io?
It works with JXcore (open sourced fork of Node.JS). JXM itself is an open source project, which you can find on github: jxm.
It's really fast and efficient, you can check some tutorials. For example, below is minimal code, that you need to run on server-side:
var server = require('jxm');
server.setApplication("Hello World", "/helloworld", "STANDARD-KEY-CHANGE-THIS");
server.addJSMethod("serverMethod", function (env, params) {
server.sendCallBack(env, params + " World!");
});
server.start();
The client's part can be found here:
Browser Client (JavaScript)
JXM also supports Java clients (runs on android) and node clients.
I am trying to get data (a user's score), from an extremely simple flash game I made, to be displayed on a simple leader board which is displayed through AngularJS. You can get a copy of all of the code here (you might need to run npm install to get it to work). I am using NodeJS/Express/Socket.io to transfer the data from the game.
Here is the code from app.js (server side):
var express = require('express'),
app = express(),
server = require('http').createServer(app),
io = require('socket.io').listen(server);
app.configure(function() {
app.use(express.static(__dirname + '/public'));
app.set('views', __dirname + '/views');
});
io.configure(function() {
io.set('transports', ['websocket','xhr-polling']);
io.set('flash policy port', 10843);
});
var contestants = [];
io.sockets.on('connection', function(socket) {
socket.on('data', function (data) {
socket.broadcast.emit(data);
});
socket.on('listContestants', function(data) {
socket.emit('onContestantsListed', contestants);
});
socket.on('createContestant', function(data) {
contestants.push(data);
socket.broadcast.emit('onContestantCreated', data);
});
socket.on('updateContestant', function(data){
contestants.forEach(function(person){
if (person.id === data.id) {
person.display_name = data.display_name;
person.score = data.score;
}
});
socket.broadcast.emit('onContestantUpdated', data);
});
socket.on('deleteContestant', function(data){
contestants = contestants.filter(function(person) {
return person.id !== data.id;
});
socket.broadcast.emit('onContestantDeleted', data);
});
});
server.listen(8000);
The key lines from above are:
socket.on('data', function (data) {
socket.broadcast.emit(data);
});
That is where I am trying to send the data from the server side to the client side. On the client side - from within my main controller, I have this.
leader-board.js (main client side javascript file):
socket.on('data', function(data) {
$scope.score.push(data);
})
// Outgoing
$scope.createContestant = function() {
$scope.$digest;
console.log($scope.score[0]);
var contestant = {
id: new Date().getTime(),
display_name: "Bob",
score: Number($scope.score[0])
};
$scope.contestants.push(contestant);
socket.emit('createContestant', contestant);
_resetFormValidation();
};
As you can see - I am trying to get the emitted data, and push it to an array where I will keep the scores. The createContestant function gets called when the user clicks a submit button from within the main index.html file.
index.html
<body>
...
<button ng-click="createContestant()" class="btn btn-success"
ng-disabled="
ldrbd.contestantName.$error.required ||
ldrbd.contestantScore.$error.required
"
>
Submit Score
</button>
...
</body>
The line console.log($scope.score[0]);, from within the createContestant function, is always undefined. I am not sure if I am emitting the data correctly from the server side with socket.io - and I am not sure if I am receiving it correctly either. I use $scope.$digest to refresh the scope because the socket.io stuff is outside of AngularJS (or so I have read). Any help would be greatly appreciated. Again - I am trying to store data emitted from a flash game into an array, however - before the data is stored, it needs to be fetched correctly - and my fetch always turns up undefined, when it should be retrieving a number which is being emitted from the game (I know that I am emitting the number from the game because I have tested it with log messages). Thanks!
UPDATE
Changed server side code to this:
socket.on('message', function (data) {
console.log(data)
score = data;
socket.emit('score', score);
})
...and client side to this:
socket.on('score', function(data) {
console.log(data);
$scope.score = data;
});
Still no luck - but I added the console.log message to the server side to confirm that the data was getting sent and received (at least by node) and it is - the output of that message is a number which is the score. The thing I am realizing is...the score is supposed to be input on the client side when the button is clicked. But the data gets emitted from the server side when the game is over...so when the button is clicked...is the data available to the client side in that moment? Is this the discrepancy?
Here is the working socket code (took me a while but I got it)!
Server side (Node/Express):
socket.on('message', function (data) {
console.log(data);
score = data;
console.log("Transfered:" + " " + score);
//
})
socket.on('score', function() {
socket.emit('sendscore', score);
})
Client side (AngularJS)
socket.on('sendscore', function(data) {
console.log(data);
$scope.score = data;
});
// Outgoing
$scope.createContestant = function() {
socket.emit('score')
//$scope.$digest;
//console.log($scope.score[0]);
var contestant = {
id: new Date().getTime(),
display_name: "Bob",
score: $scope.score
};
$scope.contestants.push(contestant);
socket.emit('createContestant', contestant);
_resetFormValidation();
};
The link in the question still works for the code if you want to try it yourself!
It was really easy setting up sessions and using them in PHP. But my website needs to deal with WebSockets. I am facing problem to set up sessions in node.js. I can easily push data without using sessions and it would work fine but when more than one tab is opened the new socket.id is created and previously opened tabs won't function properly. So I have been working on sessions and had problem accessing session store, its logging session not grabbed. I have tried with session.load as well but no luck
How do I get session object and use it in a way that opening other tabs wouldn't affect the functionality and push data from server to client on all tabs?
var express=require('express');
var http = require('http');
var io = require('socket.io');
var cookie = require("cookie");
var connect = require("connect"),
MemoryStore = express.session.MemoryStore,
sessionStore = new MemoryStore();
var app = express();
app.configure(function () {
app.use(express.cookieParser());
app.use(express.session({store: sessionStore
, secret: 'secret'
, key: 'express.sid'}));
app.use(function (req, res) {
res.end('<h2>Hello, your session id is ' + req.sessionID + '</h2>');
});
});
server = http.createServer(app);
server.listen(3000);
sio = io.listen(server);
var Session = require('connect').middleware.session.Session;
sio.set('authorization', function (data, accept) {
// check if there's a cookie header
if (data.headers.cookie) {
// if there is, parse the cookie
data.cookie = connect.utils.parseSignedCookies(cookie.parse(data.headers.cookie),'secret');
// note that you will need to use the same key to grad the
// session id, as you specified in the Express setup.
data.sessionID = data.cookie['express.sid'];
sessionStore.get(data.sessionID, function (err, session) {
if (err || !session) {
// if we cannot grab a session, turn down the connection
console.log("session not grabbed");
accept('Error', false);
} else {
// save the session data and accept the connection
console.log("session grabbed");
data.session = session;
accept(null, true);
}
});
} else {
// if there isn't, turn down the connection with a message
// and leave the function.
return accept('No cookie transmitted.', false);
}
// accept the incoming connection
accept(null, true);
});
sio.sockets.on('connection', function (socket) {
console.log('A socket with sessionID ' + socket.handshake.sessionID
+ ' connected!');
});
Take a look at this article: Session-based Authorization with Socket.IO
Your code works fine, but need 2 improvements to do what you want (send session data to clients from server):
it extracts sessionID during authorization only
it extracts session data from store by this sessionID during connection where you can send data from server to clients in an interval.
Here's the improved code:
var express = require('express');
var connect = require('connect');
var cookie = require('cookie');
var sessionStore = new express.session.MemoryStore();
var app = express();
app.use(express.logger('dev'));
app.use(express.cookieParser());
app.use(express.session({store: sessionStore, secret: "secret", key: 'express.sid'}));
// web page
app.use(express.static('public'));
app.get('/', function(req, res) {
var body = '';
if (req.session.views) {
++req.session.views;
} else {
req.session.views = 1;
body += '<p>First time visiting? view this page in several browsers :)</p>';
}
res.send(body + '<p>viewed <strong>' + req.session.views + '</strong> times.</p>');
});
var sio = require('socket.io').listen(app.listen(3000));
sio.set('authorization', function (data, accept) {
// check if there's a cookie header
if (data.headers.cookie) {
// if there is, parse the cookie
var rawCookies = cookie.parse(data.headers.cookie);
data.sessionID = connect.utils.parseSignedCookie(rawCookies['express.sid'],'secret');
// it checks if the session id is unsigned successfully
if (data.sessionID == rawCookies['express.sid']) {
accept('cookie is invalid', false);
}
} else {
// if there isn't, turn down the connection with a message
// and leave the function.
return accept('No cookie transmitted.', false);
}
// accept the incoming connection
accept(null, true);
});
sio.sockets.on('connection', function (socket) {
//console.log(socket);
console.log('A socket with sessionID ' + socket.handshake.sessionID + ' connected!');
// it sets data every 5 seconds
var handle = setInterval(function() {
sessionStore.get(socket.handshake.sessionID, function (err, data) {
if (err || !data) {
console.log('no session data yet');
} else {
socket.emit('views', data);
}
});
}, 5000);
socket.on('disconnect', function() {
clearInterval(handle);
});
});
Then you can have a client page under public/client.html at http://localhost:3000/client.html to see the session data populated from http://localhost:3000:
<html>
<head>
<script src="/socket.io/socket.io.js" type="text/javascript"></script>
<script type="text/javascript">
tick = io.connect('http://localhost:3000/');
tick.on('data', function (data) {
console.log(data);
});
tick.on('views', function (data) {
document.getElementById('views').innerText = data.views;
});
tick.on('error', function (reason){
console.error('Unable to connect Socket.IO', reason);
});
tick.on('connect', function (){
console.info('successfully established a working and authorized connection');
});
</script>
</head>
<body>
Open the browser console to see tick-tocks!
<p>This session is viewed <b><span id="views"></span></b> times.</p>
</body>