Socket.io doesn't emit from an app? (ionic) - node.js

I use node.js as server and my ip is example.com:4000. So my endpoint of socket on server side should be example.com:4000. I manage to get it work even when I try to emit something from localhost to example.com:4000.
But when I have an app (I'm using ionic with a real device) but the socket seems didn't send it out the emit of socket.io. I wonder why, it has been 2 days I try to debug this issue.
my code on server side
var server = require("http").Server(express);
var io = require("socket.io")(server);
server.listen(400);
io.on('connection', function(client) {
client.on('msg', function(data) {
console.log(data)
});
});
client side
//angular service
.factory('socket',function(socketFactory){
var myIoSocket = io.connect('http://example.com:4000');
mySocket = socketFactory({
ioSocket: myIoSocket
});
return mySocket;
});
//within my controller
socket.emit('msg',data);
To summarize, things worked on localhost but not when I try on an app?

Try to run this code, since I know that example is working:
Factory
MyApp.factory('socket', function ($rootScope) {
var socket = io.connect('http://localhost:9000');
return {
on: function (eventName, callback) {
socket.on(eventName, function () {
var args = arguments;
$rootScope.$apply(function () {
callback.apply(socket, args);
});
});
},
emit: function (eventName, data, callback) {
socket.emit(eventName, data, function () {
var args = arguments;
$rootScope.$apply(function () {
if (callback) {
callback.apply(socket, args);
}
});
})
}
};
});
Controller
MyApp.controller('MainCtrl', function($scope, socket){
$scope.users = [];
socket.emit('connection'); });
...
Server side
"use strict";
var express = require('express');
var app = express();
var server = require('http').Server(app);
var io = require('socket.io')(server);
io.on('connection', function(socket) {
console.log('connected!');
socket.on('disconnect', function() {
console.log('user disconnected');
});
});
server.listen(9000, function() {
console.log('server up and running at 9000 port');
});

Related

How can I export socket.io connection to another controller

I am stuck in a problem.
I am making a Socket.IO connection in the bin file which is working, but can anyone tell me how I can export this connection to different controller. This is my bin file code.
var app = require('../app');
var debug = require('debug')('userservice:server');
var http = require('http');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '3015');
app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
var io = require('socket.io')(server);
io.on('connection', (socket) => {
console.log('Connection made #######################################################.', socket.id);
socket.on('disconnect', () => {
console.log('Connection disconnected #######################################################.', socket.id);
});
});
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
There is plenty of techniques can be used to re-use the socket instance, an easy and simple one is to create a singular class, to be able to:
Initiate socket instance
Export the instance to other modules
socket.js:
let io;
module.exports = {
init: (server) => {
io = require('socket.io').listen(server); io.origins('*:*');
return io;
},
get: () => {
if (!io) {
throw new Error("socket is not initialized");
}
return io;
}
};
server.js:
const app = require('../app');
const http = require('http');
/**
* Get port from environment and store in Express.
*/
const port = '3015';
app.set('port', port);
/**
* Create HTTP server.
*/
const server = http.createServer(app);
const io = require('./socket.js').init(server);
io.on('connection', (socket) => {
console.log('Connection success', socket.id);
socket.on('disconnect', () => {
console.log('Connection disconnected', socket.id);
});
}
Now you can use it in other modules.
const io = require('./socket.js').get();
You could just create a socket.io controller module that exports a function that you call for every new connection.
So, in your current server file, you add this:
const {socketConnected} = require('socketController.');
And, you modify this portion to call it for each new socket:
var server = http.createServer(app);
var io = require('socket.io')(server);
io.on('connection', (socket) => {
console.log('Connection made #######################################################.', socket.id);
// tell controller about new socket (and pass the io instance)
socketConnected(socket, io);
socket.on('disconnect', () => {
console.log('Connection disconnected #######################################################.', socket.id);
});
});
Then, your socket controller can be like this:
module.exports.socketConnected = function(socket, io) {
// new socket.io socket connected
console.log(`controller: got socket.io connection ${socket.id}`);
// register appropriate event handlers on the socket here
}
We can export the socket module in every file by creating a global object in such a way.
let io;
const connectedUsers = [];
const setupSocketIO = function (server) {
io = require('socket.io')(server, { cors: { origin: '*' } });
io.on('connection', function (socket) {
connectedUsers[connectedUsers.length] = socket.id;
socket.on('getConnectedUsers', () => {
io.sockets.emit('returnConnectedUsers', connectedUsers.length);
});
socket.on('disconnect', () => {
let socketIdToRemoveIndex = -1;
for (let i = 0; i < connectedUsers.length; i++) {
if (connectedUsers[i] === socket.id) {
socketIdToRemoveIndex = i;
}
}
if (socketIdToRemoveIndex !== -1) {
connectedUsers.splice(socketIdToRemoveIndex, 1);
}
io.sockets.emit('connectedUsers', connectedUsers.length);
});
});
};
const Socket = function () {
return {
emit: function (event, data) {
io.sockets.emit(event, data);
},
to: function (roomId, event, data) {
io.sockets.to(roomId).emit(event, data);
},
};
};
exports.setupSocketIO = setupSocketIO;
exports.Socket = Socket;
And in file or componenet, we want to use.
const getAllProjects = async (req, res) => {
let Socket = require('../sockets').Socket();
Socket.emit('SOCKET_PUSH_NOTIFICATION', { data: 'This is random data' });
Socket.to('SOCKET_PUSH_NOTIFICATION', 'event', { data: 'Muhammad' });
}

Node server working only on localhost Lumen

I am making a real-time Lumen API. For that i have used Node.js to create the server.
It works perfectly fine on localhost, but not when published
This is the code for my Node Server.js
var app = require('http').createServer(handler);
var io = require('socket.io')(app);
var Redis = require('ioredis');
var redis = new Redis();
app.listen(6001, function() {
console.log('Server chalu hua');
});
function handler(req, res) {
res.writeHead(200);
res.end('');
}
io.on('connection', function(socket) {
console.log('Lijiye Nya connection bna diya gya');
});
io.on('disconnect', function(socket) {
console.log('Connection Dropped');
});
redis.psubscribe('*', function(err, count) {
//
});
redis.on('pmessage', function(subscribed, channel, message) {
console.log(channel);
message = JSON.parse(message);
console.log(message);
io.emit(channel, message.data);
})
Can someone tell what to do, to make it work in Production

how to attach socket.io to SwaggerExpress

I am using swaggerexpress middleware and swagger.
I can't get to work with socket.io
What is the proper way to attach socket.io to my server created?
'use strict';
var SwaggerExpress = require('swagger-express-mw');
var app = require('express')();
var io = require('./api/helpers/socketio');
module.exports = app;
var config = {
appRoot: __dirname
};
SwaggerExpress.create(config, function(err, swaggerExpress) {
if (err) { throw err; }
swaggerExpress.register(app);
app.listen(10010, function () {
console.log('Application is start listening on localhost:10010');
});
io.on('connection',function(socket){
console.log("A user is connected: " + socket.id);
io.emit('message', "Welcome")
});
});
io.attach(app);
With that approach, my server is not getting up, got an error on socket.io attaching to app.
If you're okay using a different port for socket.io, you could do something like this:
var io = require('socket.io')(10011);
// Or maybe in your case:
// var io = require('./api/helpers/socketio')(10011);
io.on('connection', function(socket) {
console.log('user connected');
});
On the client you'd connect to it like this:
var socket = io('http://localhost:10011');
socket.on('connect', function() {
console.log('Socket connection established');
});

function not called by nodejs ws-express on connection handler

I've implemented a websockets api on top of a swagger-express node server.
For websockets I'm using express-ws which utilises the excellent ws library.
However I have come across a problem where the function setInterval is not being called when a websocket client connects.
Confusingly though in the ws.on('connection' function the console.log('websocket connected'); does execute while the setInterval function does not.
Can someone please point out what is wrong with my code?
'use strict';
var SwaggerExpress = require('swagger-express-mw');
var app = require('express')();
module.exports = app; // for testing
var expressWs = require('express-ws')(app);
var IndexWS = require('./api/controllers/indexWS');
var config = {
appRoot: __dirname // required config
};
app.ws('/', function(ws, req) {
ws.on('connection', function(conn) {
console.log('websocket connected');
setInterval(function timeout() {
console.log('conn');
}, 500);
});
ws.on('close', function() {
console.log('The connection was closed!');
});
ws.on('error', function() {
console.log('websocket error!');
});
ws.on('message', function(msg) {
setTimeout(function timeout() {
ws.send("500 delay");
}, 500);
});
console.log('websocket connected');
});
SwaggerExpress.create(config, function(err, swaggerExpress) {
if (err) { throw err; }
// install middleware
swaggerExpress.register(app);
var port = process.env.PORT || 3030;
app.listen(port, '0.0.0.0');
if (swaggerExpress.runner.swagger.paths['/hello']) {
console.log('server running on port ' + port );
}
});

how to use socket.io to send data to a specify client ? with Angular, NodeJs,Express

I'm writing a social web with NodeJS, Express and Angular.
Now I already handled socket between server and client but I want to send a server side status of a user to only his friends, not broadcast to the whole network.
This is my code:
In client
Main.js
angular.module('appServices', ['ngResource']).
factory('socket', function($rootScope){
var socket = io.connect();
return {
on: function (eventName, callback){
socket.on(eventName, function(){
var args = arguments;
$rootScope.$apply(function(){
callback.apply(socket, args);
});
});
},
emit: function (eventName,data, callback){
socket.emit(eventName, data, function (){
var agrs = arguments;
$rootScope.$apply(function (){
if(callback){
callback.apply(socket, agrs);
}
});
})
}
};
});
Controller.js
function activityCtrl($scope, socket){
$scope.createStatus = function(){
var sttData = $scope.stt;
socket.emit('createStt',sttData);
}
socket.on('addStt',function(data){
$scope.user.activity.unshift(data);
});
socket.on('myStt',function(data){
$scope.user.activity.unshift(data);
});
}
Main.js
angular.module('webProfileApp',['appServices'])// appServices duoc goi tu services.js
.config(['$routeProvider', function($routeProvider){
$routeProvider.
when('/activity/:userId',{ templateUrl: 'partials/me.html', controller: activityCtrl });
}]);
In Serverside:
app.js
var express = require('express');
var routes = require('./routes');
var user = require('./routes/user');
var http = require('http');
var path = require('path');
var app = express();
var server = http.createServer(app);
var io = require('socket.io').listen(server);
io.sockets.on('connection',user.createStt);
User.js
exports.createStt = function(socket){
socket.on('createStt',function(dataSocket){
console.log('Save status---------');
var reqBody = dataSocket;
//
//Save data
//
socket.broadcast.emit('addStt',reqBody);
socket.emit('myStt',reqBody);
});
});
I use a variant of rooms with a special GUID...
SERVER
var on_connected = function(sockets, socket, user) {
socket.join(token(special_room_name));
}
//...
sockets.in(token(special_room_name)).emit('special_event_name', {...});
CLIENT
socket.on('special_event_name', function(info) {
$scope.users = info;
});
Note: client only receives this if we called join() on his socket, i.e. she is a memebr of this room...

Resources