socket.io not working node.js - 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");
});
});
};

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')
})
}

Socket.io works with localhost but not on Heroku server

I am currently trying to use socket.io and a node.js server to communicate with a Unity script. I have everything hooked up and working with localhost, but for some reason when I port it to my Heroku server it can't connect. I'm assuming it might have something to do with the URL's? I'm new to socket.io so any help would be appreciated.
My node.js server:
var express = require('express');
var app = express();
var expressWs = require('express-ws')(app);
var path = require('path');
var server = require('http').createServer(app);
var io = require('socket.io')(server);
io.on('connection', function(socket) {
socket.on('beep', function(){
socket.emit("speed", {data: 5});
console.log('beep recieved');
});
socket.on('change-speed', function(data) {
console.log('change speed recieved: ' + data);
socket.emit("speed", {newSpeed: data});
});
socket.on('ios-connection', function(data) {
console.log('ios connection with message: ' + data);
});
});
app.set('port', (process.env.PORT || 5000));
app.listen(app.get('port'), function() {
console.log('Node app is running on port', app.get('port'));
});
My connection URL:
ws://<heroku app name>.herokuapp.com:5000/socket.io/?EIO=4&transport=websocket
The problem is almost certainly an incorrect port number.
In your application, you are checking for process.env.PORT and if it is not set, you are defaulting to 5000.
In your ws URL however, you seem to be always expecting your application to be listening on port 5000.
You can check the config settings of your application by running the following command in the root of your project:
heroku run printenv
This will print a list of config vars, including the current set PORT value, eg:
PORT=9352
You should use this port when constructing your ws URLs, eg:
ws://your-app.herokuapp.com:9352/socket.io/?EIO=4&transport=websocket
I found the way!!.
In Unity
if you run server in the localhost. the url should have " : port"
example (port = 5000)
ws://127.0.0.1:5000/socket.io/?EIO=4&transport=websocket
but if you have deployed to **heroku
the url must delete " : port"
ws://<heroku app name>.herokuapp.com/socket.io/?EIO=4&transport=websocket
It's work for me!
I have deployed your code with minor changes and its working fine on heroku please take a look into it.
Server side app.js
var express = require('express');
var app = express();
app.set('port', (process.env.PORT || 5000));
var server = app.listen(app.get('port'), function() {
console.log('Node app is running on port', app.get('port'));
});
var io = require('socket.io')(server);
app.use(express.static("./views"));
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
next();
});
app.get('/', function (req, res) {
var path = __dirname + '/views/index.html';
console.log(path);
res.sendFile(path);
});
io.on('connection', function(socket) {
socket.on('beep', function(){
socket.emit("beep", {data: 5});
console.log('beep recieved');
});
socket.on('change-speed', function(data) {
console.log('change speed recieved: ' + data);
socket.emit("speed", {newSpeed: data});
});
socket.on('ios-connection', function(data) {
console.log('ios connection with message: ' + data);
});
});
package.json
{
"name": "socketio",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start" : "node app.js"
},
"author": "inampaki",
"license": "ISC",
"dependencies": {
"express": "^4.13.3",
"express-ws": "^0.2.6",
"socket.io": "^1.3.7"
}
}
index.html
<script src="/socket.io.js"></script>
<script>
var socket = io.connect('/');
socket.on('speed', function (data) {
console.log('speed Message Received!');
console.log(data);
});
socket.on('beep', function (data) {
console.log('beep Message Received!');
console.log(data);
});
socket.emit("beep", {beep : true});
socket.emit("change-speed", {"change-speed" : true});
socket.emit("ios-connection", {"ios-connection" : true});
</script>
note that save index.html and socket.io.js in views folder. URL on which I have deployed it is socketip
Ok, for some reason I tried everything on this question thread, and it worked. However not a single answer worked, but a combination of every one.
First, I removed the :PORT part in the URL, sort of like Chinnawat Sirima says. It is now...
ws://.herokuapp.com/socket.io/?EIO=4&transport=websocket
Then, for some reason initiating the server with this code from dangalg's answer/teyou's repo did work (I also noticed teyou's url doesn't have the port either).
var express = require('express');
var app = express();
var http = require('http').createServer(app);
var io = require('socket.io')(http);
var PORT = process.env.PORT || 3000;
(more code here)
http.listen(PORT,function(){
console.log("Listening to port " + PORT);
});
Why do I say "for some reason"? Because I still don't know what I did lol. My guess is that I was setting the server in a way Heroku didn't like, but everyday localhost does. Because localhost doesn't care.
I'm just recompiling this because I've been in frustration with this problem for the last 8 hours, more or less. So I hope this helps someone else, to not lose valuable time and sleep.
(btw, I don't have a PORT variable in my Heroku, I have some other name, I guess that's another useless line but I'm not touching this anymore in case I break it again :D).
If you have deployed your application to Heroku, remove the port number from the URL of the server as given and it should work fine.
ws://<heroku app name>.herokuapp.com/socket.io/?EIO=4&transport=websocket When you test the app locally, you can access the socket via http://localhost:YOUR_PORT_NUMBER wheres, after deployment, you don't need to specify the port.
Had a bit of a nightmare with this. Ended up reading through the docs.
Server: https://www.npmjs.com/package/socket.io
Client: https://socket.io/docs/v4/client-initialization
It seems my structure was wrong see the docs.
In conjunction with Express
const app = require('express')();
const server = require('http').createServer(app);
const io = require('socket.io')(server);
io.on('connection', () => { /* … */ });
server.listen(3000);
My full code.
const express = require('express')
const path = require('path');
const http = require('http')
const PORT = process.env.PORT || 5000
const app = express()
const server = http.createServer(app)
const cors = require("cors");
app.use(cors());
// Serve static files from the React app
app.use(express.static(path.join(__dirname, 'client/build')));
const io = require('socket.io')(server);
io.on("connection", (socket) => {
});
server.listen(PORT, () => console.log(`Server is running on port ${PORT}`));
And in my react code I am simply using.
const socket = io();
Hope this helps someone else

Express-Generator - Including socket.io (bin/www)

I've always been a bit of a Perl/PHP sorta guy, but I fancy a change and Node JS seems like the right place for me to go next.
I've watched a good few hours of tutorials on YouTube and read some posts on here - but I have come up a bit stuck.
I'd like to include socket.io in my express-generated application (v4.10.6).
At the same time though, I don't really want to include the socket.on(...) statements in one file - i'd much rather split it out like you would with a route.
Given that the express-generated app is started in bin/www, i'm confused as to where I need to require('socket.io') and point all the 'on' events to.
This post on stackoverflow, I think may answer my question - but it suggests all the socket handlers are in the ./sockets/base.js file - and I am confused by the Gofilord's response to the answer.
Please forgive my ignorance here - this is all a bit alien to me at the moment, and thank you, as always for taking the time to read this and your help.
/bin/www
#!/usr/bin/env node
var debug = require('debug')('rhubarb');
var app = require('../app');
app.set('port', process.env.PORT || 1127);
var server = app.listen(app.get('port'), function() {
debug('Express server listening on port ' + server.address().port);
});
Its typical to require socket.io in app.js and then to tell your io sever to listen to your application. Using the example you posted, that would look like this:
var debug = require('debug')('rhubarb');
var app = require('../app');
var server = require('http').Server(app);
var io = require('socket.io')(server);
app.set('port', process.env.PORT || 1127);
var server = server.listen(app.get('port'), function() {
debug('Express server listening on port ' + server.address().port);
});
The socketio docs do a really good job of explaining this. Here's an example from their homepage:
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
server.listen(80);
app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});
io.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
Update:
I typically modularize socketio setup by creating a lib called io.js in /lib with something like this:
module.exports = function(server){
var io = require('socket.io')(server);
// catch errors
io.on('error', function(err){
throw err;
})
// Set Socket.io listeners by creating a socket.io middleware
// attachEventlisteners would live in `/controllers`
io.use(attachEventlisteners);
io.on('connection', function (socket) {
// do things
});
return io; // so it can be used in app.js ( if need be )
}
then in app.js i can simply pass the server in when I require it:
var io = require('./lib/io')(server);
You dont need to do any thing further in app.js since everything is setup in /lib/io.js, but if you wanted to you could because the io server is returned.

Socket.io 1.0.6 client event

I am currently learning to use socket.io with node js but I'm having a hard time because I think something may have changed between versions. I have a litte demo using 1.0.4 in which I use something like this to send events from the client and receive them in the server:
SERVER
var socketio = require('socket.io');
var http = require('http');
var app = express();
var server = http.Server(app);
var io = socketio.listen(server);
var port = process.env.PORT || 8080;
server.listen(port, function(){
console.log("Express server listening on port " + port);
});
io.on('connection', function (socket) {
socket.emit('connected');
socket.on('myEvent', function(){
console.log('myEvent has been emitted');
});
});
CLIENT
$(document).ready(function(){
$('#button').click(function(){
emitEvent();
});
});
var socket = io.connect('http://localhost:8080/');
socket.on('connected', function () {
alert('server says I am connected');
});
function emitEvent(){
socket.emit('myEvent');
}
With both versions I can open the socket on the client and receive the 'connected' event sent later from the server than launches the alert function. The problem here is when I want to send any other event from the client. "socket.emit('myEvent');" in the emitEvent function seems to work fine for the 1.0.4 version but not for the 1.0.6 version. I have been looking for info about the changes and trying to understand the whole module but cannot get to the solution. Does anyone know what am I doing wrong? Obviously the way sending client events has changed. I would appreciate if someone could help me with this issue. Thanks in advance.
I didn't understand the problem actually. But here's the code for your functionality.
client:
var socket = io.connect();
$('#button').click(function(){
socket.emit('myEvent');
});
socket.on('connected', function(){
alert "you are connected";
});
server:
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(app);
var port = process.env.PORT || 8080;
app.listen(port);
io.on('connection', function(socket){
socket.on('myEvent', function(){
socket.emit('connected');
console.log('emmited succesfully');
});
});

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.

Resources