Node - acting as a Webserver and a client - node.js

When users do a GET /check/health, this client should talk to Server and sever should give the client the answer..
But the message from the server is not received on the client..
Client side - also acting as a webserver
var io = require('socket.io-client');
var socket = io.connect('http://localhost:4000', {reconnect: true});
var express = require('express');
var app= express();
var path = require('path');
var bodyParser= require('body-parser');
app.use(express.static(__dirname+"/public/"));
app.use(bodyParser.json());
app.set('views',path.join(__dirname,'/public/html'));
app.engine('html', require('ejs').renderFile); //specify which template engine to use
app.set('view engine', 'ejs');
app.get('/check/health',function(req,res){
//console.log('Connected Success!!');
socket.on('connect', function(socket) {
console.log('Connected!');
});
socket.emit('data', 'I need your health status');
socket.on('data', function(data) {
console.log('Message from monitoring is : ' + ': ' + data);
});
socket.on('server data', function(data) {
console.log('Received server data: ' + data);
});
});
app.listen(3000);
console.log("Server running at http://localhost:3000/'");
Server side:
var app = require('express')();
var SERVER = require('http').Server(app);
var io = require('socket.io')(SERVER);
var express = require('express');
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/sensor_db');
io.on('connection', function(socket){
console.log('connection received from Provisioning ');
// To get messages from Provisioning server
socket.on('data', function(data) {
console.log('Message from provision is : ' + ': ' + data);
});
socket.emit('server data', 'Here is yiour data - 1111');
});
SERVER.listen(4000, function(){
console.log('listening on *:4000');
});

There are a number of potential issues here, but the main one is that your server side code is missing the following very important line:
http.listen(4000);
Adding that should get you started down the right path. Also, I would suggest renaming the http variable to something else, since it's not the http module. server makes more sense to me.
Here's a more minimal example of what you're looking to do. It's missing a few things such as error handling, considering what should happen when a request to /check/health comes in and your socket.io connection isn't up, etc, but I'll leave that as an exercise for you. I also trimmed out some stuff that wasn't relevant to the question (mongoose, ejs templating, etc), so you'll have to add those back in when you're confident that this piece is working as intended.
Client Side
var io = require('socket.io-client');
var socket = io.connect('http://localhost:4000', { reconnect: true });
var express = require('express');
var app= express();
var path = require('path');
// careful here -- the socket.io connection will be made
// outside of the context of the /check/health callback,
// so you should move the connect event handler out here.
socket.on('connect', function(socket) {
console.log('Connected!');
});
app.get('/check/health',function(req,res){
// note the third argument here,
// which can be used as an acknowledgement from the server
// that your client's emit was received
socket.emit('data', 'I need your health status', function ack(data) {
console.log('data emit was acknowledged:', data);
// make sure you send something back to the requester
// or they'll just hang until timeout
return res.json(data);
});
// if you want, you could technically use socket.once('server data'),
// in this location, but this is probably going to be closer
// to the style of communication you actually want --
// which is one response to this specific single socket emit.
});
app.listen(3000);
console.log('Server listening at port 3000');
Server Side
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
var express = require('express');
io.on('connection', function(socket){
console.log('connection received from Provisioning');
// To get messages from Provisioning server
socket.on('data', function(data, ack) {
console.log('Message from provision is : ' + ': ' + data);
ack('here is your data - 1111');
});
});
server.listen(4000, function(){
console.log('socket.io server listening on *:4000');
});

Related

Socket.io with Express, emit not working within express route

Either I have a fundamental misunderstanding of how socket.io works (highly likely), or I am just finding some bug that nobody knows about (nearly impossible).
I've been trying to integrate express with socket.io. On the client side, everything works fine: user clicks button, event emits, everybody's happy.
However, let's say I want to emit this event from within an express route before rendering a page. The event never seems to be emitted. From all the questions on this that I've looked at, I'm supposed to be able to simply plug my "io" instance into my app and then access it from within my routes.
So this is my setup...
// index.js
var app = express();
var port = process.env.PORT || 3700
var io = require('socket.io').listen(app.listen(port));
io.on('connection', function (socket) {
console.log("Socket connected on port " + port)
socket.on('send', function (data) {
console.log("WAFFLES")
});
});
console.log('The magic happens on port ' + port);
require('./app/routes.js')(app, io);
// app/routes.js
module.exports = function(app, io){
app.get('/', function(req, res){
io.on('connection', function (socket) {
console.log("Hello from the route!")
socket.emit('send', {message: 'urdum'})
});
res.render('index')
})
}
So in this instance, I want to be able to go into the / route, see "Hello from the route" and then "WAFFLES" logged to the console after emitting the "send" event. Instead I get absolutely nothing.
I've tried to pass in "io" via app.set('socketio', io). But no matter what, nothing works.
I've also tried emitting the event within the route without the io.on('connection') and simply just doing
io.emit('send' ...)
OR
io.sockets.emit('send' ...)
I have a fundamental misunderstanding of how socket.io works (highly likely)
You are right,
This is typical setup for socket-io, read more in https://socket.io/docs/
// index.js
var express = require('express');
var socketio = require('socket.io');
var http = http = require('http');
var app = express();
// Attach Socket.io
var server = http.createServer(app);
var io = socketio.listen(server);
app.set('socketio', io); // <-- bind socket to app
app.set('server', server); // <-- optional
io.on('connection', function (socket) {
console.log("Socket connected on port " + port);
});
app.listen(3000);
server.listen(3001) // <-- socket port
// app.get('server').listen(3001); // <-- use server or app.get('server')
In your router, access socket by req.app.get('socketio');
// app/routes.js
module.exports = function(app, io){
app.get('/', function(req, res){
var socketio = req.app.get('socketio');
socketio.emit('send', {message: 'urdum'});
res.render('index')
})
}

How to emit message from client side [node.js + socket.io]

I am trying to emit message from client side with socket.io ...
Here is my client code:
var socket = io.connect('http://localhost/');
socket.on('connect', function(data){
setStatus('connected');
socket.emit('subscribe', {channel:'update.comment'});
});
Server:
io.sockets.on('connection', function (socket) {
socket.emit('message', { text : 'Welcome!' });
socket.on('subscribe', function (data) {
socket.join(data.channel);
redisClient.subscribe(data.channel);
});
});
Also I get this error message in console:
GET
http://localhost/socket.io?EIO=3&transport=polling&t=1442169984269-1
404 (Not Found)
Full serever:
var app = require('express')();
var http = require('http').Server(app);
var redis = require('ioredis');
var io = require('socket.io')(http);
redisClient = redis.createClient();
//look for connection errors and log
redisClient.on("error", function (err) {
console.log("error event - " + redisClient.host + ":" + redisClient.port + " - " + err);
});
io.sockets.on('connection', function (socket) {
socket.emit('message', { text : 'Welcome!' });
//on subscription request joins specified room
//later messages are broadcasted on the rooms
socket.on('subscribe', function (data) {
socket.join(data.channel);
redisClient.subscribe(data.channel);
});
});
redisClient.on('ready', function(data) {
console.log('#redis ready');
});
redisClient.on("message", function(channel, message){
console.log(channel);
var resp = {'text': message, 'channel':channel};
io.sockets.in(channel).emit('message', resp);
});
http.listen(3000, function(){
console.log('Listening on Port 3000');
});
New Problem Recognized:
Your server is listening on port 3000, but you are attempting to connect on port 80. The error message http://localhost/socket.io?EIO=3&transport=polling&t=1442169984269-1 has no port number on it so that defaults to port 80.
That error message means that your server-side socket.io code is not initialized correctly and thus is not listening for the HTTP request that starts all webSocket connections so when the browser tries to connect on that URL to initiate a socket.io connection, there's nobody on the server-side listening so the web server returns a 404 error back to the browser.
If you are using Express, this is the minimal socket.io initialization to hook it into your server:
var express = require('express');
var app = express();
var server = app.listen(8081);
var io = require('socket.io').listen(server);
For a plain HTTP server, this is the minimal socket.io initialization:
var app = require('http').createServer(handler)
var io = require('socket.io')(app);
app.listen(80);
As always, if you show us the socket.io and web server initialization code you are using, we can help you better with your specific code issue.

socket.io not working node.js

I am not able to run socket.io code in node.js, console.log() is also not displaying when running the code. Below is the code.
app.js
var express = require('express');
var http = require('http');
var app = express();
app.set('port', process.env.PORT || 3000);
app.post('/testStream',test.testStream);
var server = http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
module.exports.appServer = server;
and I have created a test.js file where I am accessing this exported variable appServer.
var server = require('../app.js');
exports.testStream = function(req,res){
var io = require('socket.io').listen(server.appServer);
io.on('connection',function(socket){
console.log("in socket");
fs.readFile('E:/temp/testimg.png',function(err,buf){
socket.emit('image',{image: true,buffer: buf});
console.log("test image");
});
})
}
when the code runs it stucks and not showing the console.logs(). What I am doing wrong over here. Any help is very much appreciated.
I would suggest following the code structure as suggested in socket.io docs.
Also, you should not be calling io.listen or io.on('connection') inside your testStream express middleware. These are things you should only be doing once, and ideally they should happen during startup, inside app.js and not in reaction to a POST request. In fact, I'm not sure what the purpose of your testStream middleware is, its not even returning any response (eg res.end())
If you want to handle socket connections in a separate module you can, but instead of exporting your app's server the way you are, try passing the io instance as variable to your submodule. In short, try this:
app.js
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
var test = require('./test')(io);
app.set('port', process.env.PORT || 3000);
server.listen(app.get('port'), function() {
console.log('Express server listening on port ' + app.get('port'));
});
test.js
module.exports = function(io) {
io.on('connection', function(socket) {
console.log("in socket");
fs.readFile('E:/temp/testimg.png', function(err, buf) {
socket.emit('image', {
image: true,
buffer: buf
});
console.log("test image");
});
});
};

How to connect Two Socket.io Node Application using Socket.io-client in Node js

In my application i need to connect two socket.io node applications.Using socket.io-client we can do like this.But i don't know how socket.io-client works and where to include that.
First Node Application
var express = require('express')
, http = require('http');
var app = express();
app.use(function (req, res) {
app.use(express.static(__dirname + '/public'));
});
var server = http.createServer(app);
var io = require('socket.io').listen(server);
server.listen(3000);
io.sockets.on('connection',function(socket){
socket.on('eventFiredInClient',function(data){
socket.emit('secondNodeAppln',data);// i need to get this event in my 2nd node application how can i do this by using socket.io-client
});
});
Second Node Application
var express=require('express');
var http=require('http');
var app=express();
app.configure(function(){
app.use(express.static(__dirname + '/public'));
});
var server = http.createServer(app);
var serverAddress = '127.0.0.1';
var serverPort = 3000; //first node appln port
var clientio = require('socket.io-client');
var socket = clientio.connect(serverAddress , { port: serverPort });
socket.on('connect', function(){
console.log('connected');
});
socket.on('disconnect', function(){
console.log('disconnected');
});
var io = require('socket.io').listen(server);
server.listen(6509);
//here i need to get the 'secondNodeAppln' event raised in first node application.How can i do this.
You need to create a socket.io client in your first app:
var io = require('socket.io').listen(server); // this is the socket.io server
var clientio = require('socket.io-client'); // this is the socket.io client
var client = clientio.connect(...); // connect to second app
io.sockets.on('connection',function(socket) {
socket.on('eventFiredInClient',function(data) {
client.emit('secondNodeAppln', data); // send it to your second app
});
});
And in your second app, just listen for those events:
io.sockets.on('connection', function (socket) {
socket.on('secondNodeAppln', function(data) {
...
});
});
There's a bit of a race condition because the code above doesn't wait for a connect event on the client socket before passing events to it.
EDIT see this gist for a standalone demo. Save the three files to a directory, start the servers:
node serverserver &
node clientserver
And open http://localhost:3012 in your browser.

Broadcast method with Express.io

I have a problem with Express.io: I try to create a chat but I am not able to use the Broadcast method.
No error message, but nothing happens.
app.js
var express = require('express.io')
, index = require('./routes/index.js')
, http = require('http')
, path = require('path');
var app = express();
app.configure(function(){
//configure options
});
app.http().io();
app.get('/', index.index);
app.io.route('ready', function(req) {
req.io.broadcast('newUser');
});
app.listen(app.get('port'), function(){
console.log("Express server listening on port " + app.get('port'));
});
user.js
io = io.connect();
io.emit('ready');
io.on('newUser', function(data) {
console.log("New user !!");
});
Error 2
WebSocket connection to 'ws://tchat.aws.af.cm/socket.io/1/websocket/n8Jm9Q7YYL8YdPRN4dxU' failed: Unexpected response code: 502
req.io.broadcast broadcasts to all connected clients except the client associated with the request. You should use app.io.broadcast to broadcast to all connected clients.
See the example given : https://github.com/techpines/express.io/tree/master/examples/broadcasting

Resources