Socket.io connects but does not receive message on the client - node.js

I implemented the server and client with socket.io and the server is working correctly, when some client connects it logs me in, but when I emit an event it does not arrive at the client, it follows the code to analyze:
And the console.log from socket object it says this:
connected:false,
disconnected:true
Server:
'use strict';
const chalk = require('chalk');
const _ = require('lodash');
const fs = require('fs');
let options = {
key: fs.readFileSync("privkey.pem"),
cert: fs.readFileSync("cert.pem")
};
const app = require('express')(options);
const https = require('https').Server(app);
const io = require('socket.io')(https,{origins:'*:*'});
const bodyParser = require('body-parser');
const multer = require('multer'); // v1.0.5
const upload = multer(); // for parsing multipart/form-data
const sockets = {};
app.use(bodyParser.json()); // for parsing application/json
app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded
https.listen(3002, function () {
console.log(chalk.yellow("Serviço rodando na porta 3002"));
});
io.on('connection', function (socket) {
console.log(chalk.green("Cliente Conectado"));
sockets[socket.id] = socket;
socket.on('disconnect', function () {
console.log(chalk.red("Cliente Disconectado"));
delete sockets[socket.id];
});
});
app.post('/atualizador', upload.array(), function (req, res) {
_.each(sockets,function(socket,idSocket){
console.log(idSocket);
socket.emit('posicao',req.body);
});
res.send('Atualizador ON');
});
Client:
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.4/socket.io.js"></script>
<script>
localStorage.debug = '*';
const socket = io.connect('https://localhost:3002/atualizador',{'forceNew': true});
console.log(socket);
socket.on('connection', function (socket) {
console.log(socket);
socket.on('posicao', function (msg) {
console.log("Ok");
console.log(msg);
});
socket.on('teste', function (msg) {
console.log("Ok");
console.log(msg);
});
});
</script>

Related

My socket event don't trigger when I am emit it in Nodejs

My socket event doesn't trigger when I emit it in Nodejs, I know it because I don't see "Pizza" in my console.
This is my code:
const express = require("express");
const cors = require("cors");
const app = express();
const http = require('http');
const server = http.createServer(app);
const { Server } = require("socket.io");
const io = new Server(server, {
});
app.use((req, res, next) => {
req.io = io;
next()
})
app.use(cors());
io.on('connection', (socket) => {
socket.on("dummy_event", (data) => {
console.log(`Socket 🍕`); // I don't see this message in my console
if(!data.name) return;
})
});
app.get("/socket_test", (req, res) => {
req.io.emit("dummy_event", {name: "pizza"})
return res.json({data: 'dummy text'})
})
server.listen(4000, () => {
console.log(`Server Started on Port 4000`);
})

Sending Object to group of users Node.js by using Socket.IO

I am using Node.js with Express.js and for realtime data I am using socket.io.
I am trying to create on booking app.
So when the user will request through REST api the server will store the information to mongoDB via mongoose and after that the same data will be send to other users.
I am using router for different paths. below is my server.js
var express = require('express');
const mongoose = require('mongoose');
const cors = require('cors');
const app = express();
const server = require('http').Server(app);
const io = require('socket.io')(server);
const routes = require('./routes/routes');
const port = process.env.PORT || 8080;
app.use(express.json());
app.use(cors())
app.use(express.urlencoded({ extended: false }));
app.set('socketio', io);
app.use(routes);
mongoose.Promise = global.Promise;
mongoose.connect(
'mongodb://localhost:27017/myapp',
{ useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex: true, }
).then(() => {
console.log('db connected');
}).catch(err => {
console.log(err,"hello 1998");
});
server.listen(8080);
And below is my route
const { Router } = require('express');
var router = Router();
const { main } = require('../helper/db_main')
const { checkAuthentication } = require('../helper/auth')
router.use('/api/v1/services',main,checkAuthentication,require('../controllers/services'));
router.use('/api/v1/category',main,checkAuthentication,require('../controllers/category'));
router.use('/api/v1/socket',main,checkAuthentication,require('../controllers/socket'));
module.exports = router;
and below is the place where I am trying to send/emit data to specific user but it is not working on client side i.e not able to see emit message on front-end side.
const list_all_category = (req,res) => {
console.log("Hjdnckjsdck")
var io = req.app.get('socketio');
// global.io.to("notify_me").emit("message", "hello ftomr");
let result_data
category.list_all_category().then(save_res => {
if (save_res)
result_data = res.status(200).send(save_res)
else{
result = 'fail'
res.send()
}
})
console.log("Here is ninja",io.id)
io.on('connection', function(socket){
console.log(socket.id); // same respective alphanumeric id...
})
io.sockets.on('connect', function(socket) {
const sessionID = socket.id;
})
io.on('notify',function(){
console.log("Galgotia")
})
io.sockets.emit('chat_message', 'world');
}
make use of this
socket.broadcast.to('ID').emit( 'send msg', {somedata : somedata_server} );
you can het each socket id for a specific user by using ${Socket.id}
If you are emitting anything always send the socket.id of a user to the client and send them back to the server.

How to send message to frontend in case of MongoDb connection Failed

Is there any way to send error to frontend on mongoDb connection error.I had tried in a different different way but I didnt get a solution.
var express = require('express');
var session = require('express-session');
var MongoDBStore = require('connect-mongodb-session')(session);
var store = new MongoDBStore(
{
uri: config.connectionString,
collection: 'tbl_session'
});
// Catch errors
store.on('error', function(error) {
app.get('/',function(req,res){
res.send('NOT Connected....')
});
});
You can use web sockets to push this information to the UI.
const express = require('express');
const app = express();
const path = require('path');
const server = require('http').createServer(app);
const io = require('../..')(server);
const port = process.env.PORT || 3000;
var session = require('express-session');
var MongoDBStore = require('connect-mongodb-session')(session);
var store = new MongoDBStore(
{
uri: config.connectionString,
collection: 'tbl_session'
});
// Catch errors
store.on('error', function(error) {
socket.emit('mongodb-failed', error)
});
});
server.listen(port, () => {
console.log('Server listening at port %d', port);
});
// Routing
app.use(express.static(path.join(__dirname, 'public')));
io.on('connection', (socket) => {
// when socket emits 'mongodb-connection-failed', this listens and executes
socket.on('mongodb-failed', (data) => {
// we tell the client to execute 'new message'
socket.broadcast.emit('mongodb-connection-failed', {
errorDetails: data
});
});
});
now at client side:
var socket = io();
socket.on('mongodb-connection-failed', () => {
console.log('you have been disconnected');
//do more whatever you want to.
});
This above example is using socket.io.
You can use any web socket library, see more here

How can i share socket.io into other modules in nodejs?

I have the following structure of my project in node
project structure
in a app.js, let's say i have a app.js like this
'use strict'
const express = require('express');
const realtime = require('./controllers/realtime');
const app = express();
const server = require('http').Server(app);
var sessionMiddleware = session(sessionConfig);
realtime(server,sessionMiddleware);
in a controllers/realtime.js
"use strict";
const config = require("../config");
module.exports = (server,sessionMiddleware) => {
const io = require('socket.io')(server);
io.use(function(socket, next) {
sessionMiddleware(socket.request, socket.request.res, next);
});
io.on('connection', (socket) => {
socket.on('statusConnetion',(data)=>{
console.log(data)
});
socket.on('disconnect', function () {
console.log(socket.id,"Un socket se desconecto");
});
console.log(`New socket connection: ${socket.id}`);
});
}
in controllers/cargos.js
const express = require('express');
const router = express.Router();
let cargos = {};
cargos.update = (req, res, next) =>{
//How can I use sockets here?
}
module.exports = cargos;
How can I use sockets in the file cargos.js and other controllers?
You can export not only the function that initiates the server, but a class that handles all the socket.io connection and functionality. This class will be a singleton and will have functions that uses the connection, and can be usable in the different modules.
example:
app.js:
'use strict'
const express = require('express');
const realtime = require('./controllers/realtime');
const app = express();
const server = require('http').Server(app);
var sessionMiddleware = session(sessionConfig);
realtime.connect(server,sessionMiddleware);
realtime.js:
let connection = null;
class Realtime {
constructor() {
this._socket = null;
}
connect(server,sessionMiddleware) {
const io = require('socket.io')(server);
io.use(function(socket, next) {
sessionMiddleware(socket.request, socket.request.res, next);
});
io.on('connection', (socket) => {
this._socket = socket;
this._socket.on('statusConnetion',(data)=>{
console.log(data)
});
this._socket.on('disconnect', function () {
console.log(socket.id,"Un socket se desconecto");
});
console.log(`New socket connection: ${socket.id}`);
});
}
sendEvent(event, data) {
this._socket.emit(event, data);
}
registerEvent(event, handler) {
this._socket.on(event, handler);
}
static init(server,sessionMiddleware) {
if(!connection) {
connection = new Realtime();
connection.connect(server,sessionMiddleware);
}
}
static getConnection() {
if(!connection) {
throw new Error("no active connection");
}
return connection;
}
}
module.exports = {
connect: Realtime.init,
connection: Realtime.getConnection
}
cargos.js:
const express = require('express');
const router = express.Router();
let cargos = {};
cargos.update = (req, res, next) =>{
const connection = require('./controllers/realtime').connection();
connection.sendEvent("update", {params: req.params});
}
module.exports = cargos;
Use separate endpoints for each controller like:
var io = require('socket.io').listen(80);
var user_controller = require('./controllers/user');
var chat_controller = require('./controllers/chat');
var user= io
.of('/user')
.on('connection', function (socket) {
user_controller.userData(user,socket);
});
var chat = io
.of('/chat')
.on('connection', function (socket) {
chat_controller.chatData(chat,socket);
});
And in controller simply export the module like this:
module.exports.chatData = function(endpoint,socket){
// this function now expects an endpoint as argument
socket.on('chat',function(newsreel){
// as is proper, protocol logic like
// this belongs in a controller:
endpoint.emit(chatreel); // broadcast chat to everyone subscribing
// to our endpoint/namespace
});
}
Same way you can use socket.io in multiple controllers by separating endpoints

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