I have two independent applications (frontEnd and BackEnd). The backEnd is in NodeJS using express framework and the FrontEnd is in AngularJS. Is it possible to use socket.io to send a message from the server (NodeJS) to the client (AngularJS)? How I can do that? I've tried with the following code but it is not working:
server code
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
io.sockets.on('connection', function(socket) {
//This message is not showing
console.log("socket");
socket.volatile.emit('notification', {message: 'push message'});
});
client code
angular.module('pysFormWebApp')
.factory('mySocket', function (socketFactory) {
var mySocket = socketFactory({
prefix: 'foo~',
ioSocket: io.connect('http://localhost:3000/')
});
mySocket.forward('error');
return mySocket;
});
angular.module('formModule')
.controller('typingCtrl', ['$scope', 'mySocket', typingCtrl]);
function typingCtrl ($scope, mySocket) {
mySocket.forward('someEvent', $scope);
$scope.$on('socket:someEvent', function (ev, data) {
$scope.theData = data;
console.log(data);
});
thanks for the help
This is how I set my connection up. I'm not sure if it's the best way, but it definitely works and I haven't had any performance issues to date.
Client Code:
angular.module('whatever').factory('socket', function ($rootScope) {
var socket = io.connect('yourhost');
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);
}
});
})
}
};
});
angular.module('whatever').controller("MainCtrl", MainCtrl);
function MainCtrl($scope, socket) {
socket.on('channelname', function(data) {
console.log("message: " + data.message);
});
}
Server Code:
var Express = require('express');
var app = new Express();
var server = Http.createServer(app);
var io = require('socket.io')(server);
io.on('connection', function(socket) {
socket.emit("channelname", {
message: "messagecontent"
});
});
Related
Trying to connect with Angular js + socket.io to the server (Node.js - nestsJS)
I have both React and Angular app
in react app everything is work
in Angularjs I got always "ping timeout" and then it try to recconect - on the server I saw the connection and it pass the authentication flow.
when I going to the network tab(WS) I got my events after authenticated in the backend so it looks like its a client issue
so every ~30sec the console output disconnect + reason "ping timeout"
Angular code -socket service
.factory('socket', socket);
socket.$inject = ["$rootScope"];
function socket($rootScope) {
const options = {
transports:['websocket'],
// allowUpgrades: false,
query: {
token : "token",
},
forceNew: true
}
var socket = io.connect('/', { ...options, path: `/socket.io` });
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:
socket.on('connect', function (data) {
console.log("connect")
});
socket.on('connection', function (data) {
console.log("connect")
});
socket.on('disconnect', function (data) {
console.log("disconnect")
console.log(data)
});
socket.on('events-test', function (data) {
console.log("test")
console.log(data)
})
in the network tab i can see the "events-test" events and it will create a new "ws" tab evrey reconnection
Solved by change the socket-io client version to 2.3.0
Use socketio version 2 on the client side to match the server. 3 and 4 are incompatible with server v2
I am using Node(server) + Angular(client) to implement socket in my application.
Angular bower.json socket components : "angular-socket-io":
"^0.7.0","socket.io-client": "^1.7.2",
Node js socket component in package.json : "socket.io": "^1.7.3",
I am seeing this below web socket error in my chrome browser console :
WebSocket connection to
'wss://ireporter.apple.com/uitracker/socket.io/?EIO=3&transport=websocket&sid=4qBY-qoxEzUQZOvUAACb'
failed: Error during WebSocket handshake: net::ERR_CONNECTION_RESET
WrappedWebSocket # VM43:161
This error happens probably only in a production environment. Cannot remember seeing this error in when running the application in local.
Also posting ONLY the socket related code from both server and client side :
Node js server-side code
start.js file
var express = require('express');
var configure = require("./config/configure");
var logger = require("./config/components/logger")
var app = express();
var server = require('http').Server(app);
server.listen(process.env.PORT || config.port, function() {
logger.info("Express server listening on port", config.port );
});
//Configure with all the basic middlewares and configs
configure(app,server);
configure.js file
var socket = require('./middleware/socket/socket.js');
module.exports = function (app,server) {
app.use(socket(server));
}
socket.js file
"use strict";
var logger = require("../../components/logger");
module.exports = function(server){
var io = require('socket.io')(server, {path: '/appname/socket.io'});
require('./socketServer.js')(io, logger);
return function (req, res, next) {
req.io = io;
next();
};
};
socketServer.js
//export function for listening to the socket
module.exports = function(io, logger) {
io.on('connection', function(socket) {
socket.on('notification:update', function(data) {
io.emit('notification:update', data);
});
});
};
Angular js Client Side code :
Socket.js
MyApp.factory('Socket', function ($rootScope) {
var socket = io.connect('' , {path: '/appname/socket.io'});
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);
}
});
})
}
};
});
notificationController.js
Socket.on('notification:update', function(data) {
});
-- Could anyone suggest how to resolve the console error?
Turns out there was another reverse proxy in front of your server that I had no control of. Please check your server setings. the problem is not about the code.
Error during WebSocket handshake: net::ERR_CONNECTION_RESET
Also try this one to test your server side.
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.7.2/socket.io.js"></script>
<script>
/*var socket = io('', {
path: '/appname/socket.io'
});*/
var socket = io.connect('' , {path: '/appname/socket.io'});
socket.on('notification:update', function (message) {
console.log('notification:update ', message);
});
setTimeout(function() {
console.log('emit demo');
socket.emit('notification:update', 'DEMO');
}, 1000);
socket.on('connect', function (data) {
console.log('connection');
});
</script>
//backend code
var express = require("express");
var app = express();
var http = require('http');
var startServer=http.createServer(app);
var socketIO = require('socket.io').listen(startServer);
startServer.listen(8080, function () {
console.log('server running on',8080)
});
socketIO.on('connection', function (socket) {
console.log('>>>>>>>>>>>>>>>>>>>>>>>>>>>>connected')
var userSocketObject = {};
userSocketObject.socket_id = socket.id;
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
//index.html code angularjs
var socket = io.connect('http://127.0.0.1:8080');
socket.on('news', function(data){
console.log(data);
socket.emit('my other event', {my: 'data'});
});
I'm trying to connect but I'm getting an error in the browser:
GET http://127.0.0.1:8080/socket.io/?EIO=3&transport=polling&t=LV9VGzC" Error (404): "Not found"
i have resolved the problem , the problem was in directory path app.use(express.static(path.join('public')))
Try changing your backend code into
var socketio = require('socket.io')(startServer, {
path: '/socket.io-client'
});
socketio.on('connection', function (socket) {
socket.on('my other event', function (data) {
console.log(data);
});
});
And on the clientside, the easiest way is to follow the instructions given in this repo: https://github.com/btford/angular-socket-io
I am trying socket.io authorization with jwt in my MEAN stack project. I have problem about socket object won't carry jwt token after I log out and relog in.
when I log in , token will store in local storage
UsersSvc.login($scope.user).success(function(data){
if (data.success) {
store.set('jwt', data.token);
}
then angular socket factory will retrieve jwt from local storage and send to server
.factory('SocketSvc',[ 'store',
function (store) {
this.initSocket = function(){
return io.connect('http://localhost:3000',{ query : 'token=' + store.get('jwt')});
};
var socket = this.initSocket();
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);
}
});
})
},
};
however; after I logged out
$scope.logout = function(){
var account = UsersSvc.currentAccount();
SocketSvc.emit('logout', { account : account});
$state.go('anon.login');
};
then jwt toke will be remove from local storage
if (toState.name == "anon.login") {
store.remove('jwt');
when I log in agin, token in socket query is gone while you logged in successfully. I am dealing with this problems several days. I don't know what happened.
The only way let server get token again is that refresh the page agin manually.
or close the tab and open a new page then log in agin.
My assumption is the problem of angular factory since it is singleton that it's can't be modified.
I don't know it is right or wrong or how to solve the problem. If you have any suggestion. please let me know
I solved this by wrapping the initSocket code into a function in the return block
you are right in pointing that token is null as the user is not logged in.
this.initSocket = function(){
return io.connect('http://localhost:3000',{ query : 'token=' + store.get('jwt')});
};
var socket = this.initSocket();
the above should go inside return block and called once in any Controller for initializing the socket with a valid token
My soultion:
angular.module('mean1App')
.factory('socket', function(socketFactory, $rootScope, Auth) {
var socket = null;
return {
socket: socket,
init: function(){
var ioSocket = io.connect('http://localhost:9000', {
// Send auth token on connection, you will need to DI the Auth service above
'query': 'token=' + Auth.getToken(),
path: '/socket.io-client'
});
socket = socketFactory({
ioSocket: ioSocket
});
},
...
...blah
});
My purpose is to create a realtime counter. Actually I'm creating files with my server. And I want for every created file, the counter to be incremented (the client should see the number of files in the browser growing...)
How can I exactly do that using Socket.io, AngularJS and Express.js ?
P.S : I have already written some code, but vainly.
EDIT 1 :
public/core.js
var app = angular.module('app', []);
app.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 args = arguments;
$rootScope.$apply(function(){
if(callback){
callback.apply(socket.args);
}
});
})
}
};
});
function mainController($scope, $http, socket) {
$scope.formData = {};
socket.on('number', function (data) {
console.log("Socket on number core.js !");
$scope.number = data.numberOfFiles;
});
$scope.initialize = function() {
$scope.formData.search = "";
console.log("initialize() body !");
};
$scope.search = function() {
socket.emit('next', {
message: "next"
});
console.log("search() body !");
$http.post('/search', $scope.formData)
.success(function() {
$('input').val('');
})
.error(function(data) {
console.log('Error: ' + data);
});
};
}
app.js
/**
* Module dependencies.
*/
var express = require('express');
var request = require('request');
var http = require('http');
var path = require('path');
var url = require('url');
var cheerio = require('cheerio'); // builds the DOM tree
var fs = require('fs');
var app = express();
// all environments
app.configure(function() {
app.use(express.static(__dirname + '/public')); // set the static files location /public/img will be /img for users
app.use(express.logger('dev')); // log every request to the console
app.use(express.bodyParser()); // pull information from html in POST
app.use(express.methodOverride()); // simulate DELETE and PUT
app.use(express.json());
app.use(express.urlencoded());
app.use(app.router);
});
// app.listen(8080);
// console.log("App listening on port 8080");
var server = http.createServer(app);
var io = require('socket.io').listen(server);
server.listen(8080);
var numberFiles = 1;
app.post('/search', function(req, res){
var keyword = req.body.search;
for(var i = 0; i < 100; i++) {
// The results' page URL
// some long logic that creates files and increments numberFiles
numberFiles++;
}
});
io.sockets.on('connection', function (socket) {
socket.on('next', function (data) {
socket.emit('number', {
numberOfFiles: numberFiles
});
});
});
app.get('/', function(req, res) {
res.sendfile('./public/index.html'); // load the single view file (angular will handle the page changes on the front-end)
});
Have you tried:
SERVER
io.sockets.on('connection', function (socket) {
socket.on('next', function (data, respond) {
respond({
numberOfFiles: numberFiles
});
});
});
CLIENT
socket.emit('next', {
message: "next"
}, function(data){ // data.numberOfFiles ... };