get socket value from outside(socket.io) - socket.io

let app = require('express')();
let server = require('http').Server(app);
let io = require('socket.io')(server);
io.on('connection', function (socket) {
// I want to get this value from outside
})
I want to know how to use value socket from ourside .. I have to use socket.emit() in another function
const WebSocket = require('html5-websocket');
const agent_websock = new WebSocket('ws://ip:post/');
agent_websock.onmessage = function (m) {
let msg = JSON.parse(m.data);
console.log(msg, 'agent');
socket.emit('news', {msg: msg});
};

You can get socket value from outside by the following way
==>app.js
var express = require('express');
var socket = require('./socketServer');
var app = express();
var server = app.listen(3000, function () {
console.log('Listening on port 3000 ...');
});
socket.socketStartUp(server);
module.exports = app;
==>helper.js
var helperFunction = {}
helperFunction.emitMessage = function (socket) {
socket.emit('event_name',{'key':'value'})
}
module.exports = helperFunction;
==>socketServer.js
var io = require('socket.io')();
var helper = require('helper');
var socketFunction = {}
socketFunction.socketStartUp = function (server) {
io.attach(server
io.on('connection', function (socket) {
console.log("New user is connected with socket:", socket.id);
helper.emitMessage(socket);
})
}
module.exports = socketFunction;
Hope this answer is solved your query

Related

I am getting get polling-xhr.js:157 404 error on my website

I am using server.js code
const { startCon } = require('./server/WaConnection')
const http = require('http');
const express = require('express');
const app = express();
const server = http.createServer(app);
const router = express.Router();
const { Server } = require('socket.io');
const io = new Server(server);
app.use(express.json());
app.use(express.urlencoded({ extended: true, limit: '50mb', parameterLimit: 1000000 }))
app.use(router);
require('./server/Routes')(router)
io.on('connection', (socket) => {
socket.on('StartConnection', async (device) => {
startCon(device, socket)
return;
})
socket.on('LogoutDevice', (device) => {
startCon(device, socket, true)
return
})
})
server.listen(process.env.PORT_NODE, () => {
console.log(`Server running on port ${process.env.PORT_NODE}`);
})
I am getting the error again and again that
enter image description here
I will be very thank full if you reslove my issue

errors creating test for passport using mocha

I've been working a while on getting a test to work with Mocha and Passport. I tried a couple articles on here, but I can't get them to work.
Currently, I have installed supertest and I'm trying that.
process.env.NODE_ENV = 'test';
var chai = require('chai');
var chaiHttp = require('chai-http');
var app = require('../app');
//var request = require('supertest')//(app);
//var server = request.agent(app);
//var Strategy = require('passport-strategy');
var Strategy = require('passport-local').Strategy;
var m_ticket_data = require('../model/ticket');
var m_Kbase_data = require('../model/Kbase');
var m_KbaseScript_schema = require('../model/KbaseScript');
var should = chai.should();
var expect = chai.expect;
chai.use(chaiHttp);
chai.use(require('chai-passport-strategy'));
describe('Ticket', function() {
var user, info;
before(function(done) {
console.log("hello from strategy");
chai.passport.use( new Strategy(function(username, password, done){
console.log("hello from strategy2");
done(null, { id: '1234' }, { scope: 'read' });
}
))
.success(function(u, i) {
user = u;
info = i;
done();
})
.req(function(req) {
//req.headers.authorization = 'Bearer vF9dft4qmT';
})
.authenticate();
done();
});
it ('blankout the database', function(done){
m_ticket_data.remove({}, function(){
done();
});
});
it('looks for a blank from /ticket/all', function (done) {
chai.request('http://127.0.0.1:5000')
.get('/ticket/all')
.end(function (err, res) {
res.status.should.equal(200);
console.log(res.body);
//expect(res.body).to.deep.equal({});
done();
});
});
});
I can't create a temp user for testing, so I was thinking I was going to have to overwrite the authentication. However, I'm having a problem doing that. I found this npm (https://github.com/jaredhanson/chai-passport-strategy), and I'm trying this as the latest.
This is a test I created that works fine. I don't need to authenticate for it.
process.env.NODE_ENV = 'test';
var chai = require('chai');
var chaiHttp = require('chai-http');
var server = require('../app');
var m_Kbase_data = require('../model/Kbase');
var m_KbaseScript_schema = require('../model/KbaseScript');
var should = chai.should();
var expect = chai.expect;
chai.use(chaiHttp);
describe('KBasefull', function() {
m_Kbase_data.collection.drop();
it('need to add a kbase article for testing /KBase', function (done) {
chai.request('http://127.0.0.1:5000')
.post('/kbase')
.send({Problem: "Problem", description: "Description", resolution: "Something to fix"})
.end(function(err, res){
res.should.have.status(200);
done();
});
});
}

Can't use Express to send data back to client more than once

In my app, I send a post request to the server with data containing a CSV file:
$.ajax({
type:"POST",
contentType: "application/json",
url:"/",
data: JSON.stringify({fileData:My_CSV_FILE}),
success: function(csvJson) {
console.log('in the done block!');
//can use csvJson in this handler
});
});
Note: I'm posting to the home route, and I am able to get a response with the data converted from the server. The problem is that whether I run on localhost or Heroku, I am only able to trigger the POST request once, then I have to restart the server (even if I refresh the page). So I know the issue is with my route somewhere:
UPDATED TO INCLUDE FULL SERVER FILE:
'use strict';
const express = require('express');
const csvtojson = require('csvtojson');
const PORT = process.env.PORT || 3000;
const bodyParser = require('body-parser');
const Converter = require('csvtojson').Converter;
var converter = new Converter({});
let app = express();
app.use(bodyParser.json({limit: '300kb'}));
app.use(express.static(__dirname +'/public'));
app.post('/',function(req,res) {
var csvFile = (req.body.fileData);
converter.fromString(csvFile, function(err, result) {
if(!err) {
console.log(result);
res.json(result);
}else {
res.json({error: 'Could not convert'});
}
})
});
app.listen(PORT, () => {
console.log(`app listening on port ${PORT}`);
});
I'm using Express 4. Again, everything works, but only once. When I run Heroku logs, or check the console on localhost I get:
Error: Can't set headers after they are sent.
But I don't understand how I'm re-setting them.
If wanting to run on localhost, here is a link to the projects github: https://github.com/qctimes/calendar_export
You should move the converter instantiation to be done inside the app.post callback method. This way it will instantiate a new object at every request.
This is is how your code should be:
'use strict';
const express = require('express');
const csvtojson = require('csvtojson');
const PORT = process.env.PORT || 3000;
const bodyParser = require('body-parser');
const Converter = require('csvtojson').Converter;
let app = express();
app.use(bodyParser.json({limit: '300kb'}));
app.use(express.static(__dirname +'/public'));
app.post('/',function(req,res) {
var csvFile = (req.body.fileData);
var converter = new Converter({}); // instantiation is done here
converter.fromString(csvFile, function(err, result) {
if(!err) {
console.log(result);
res.send(result);
}else {
res.send({error: 'Could not convert'});
}
});
});
app.listen(PORT, () => {
console.log(`app listening on port ${PORT}`);
});

Laravel IO Socket and redis over SSL https connection

Currently have IO sockets with laravel broadcasting with redis working perfectly. Until I then set up an SSL cert on the domain.
I have redis-server running on port 3001.
Then there is a socket.js set to listen to 3000.
My JS on the page I listen via io('//{{ $listen }}:3000').
Any guidance would be great on how to get this working over https. Would I just use 443 as the port?
Thanks.
My socket.js
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var Redis = require('ioredis');
var redis = new Redis();
redis.subscribe('notifications', function(err, count) {
});
redis.on('message', function(channel, message) {
console.log('Message Recieved: ' + message);
message = JSON.parse(message);
io.emit(channel + ':' + message.event, message.data);
});
http.listen(3000, function(){
console.log('Listening on Port 3000');
});
First, setup your serverOptions object:
var serverOptions = {
port: 3000,
host: 127.0.0.1, //address to your site
key: '/etc/nginx/ssl/your_site/server.key', //Or whatever the path to your SSL is
cert: '/etc/nginx/ssl/your_site/server.crt',
NPNProtocols: ['http/2.0', 'spdy', 'http/1.1', 'http/1.0']
}
For the NPNProtocols, you may not care for all of them, but they're provided for reference.
Now just create the server:
var app = require('https').createServer(serverOptions),
io = require('socket.io')(app);
This should be pretty plug and play into your source at his point.\
As a side note your stuff is completely wide open and anyone can listen on your web socket, so nothing should be sent that is private through here. If you need to make your data private, then you're going to need 1 of two things;
Something like JWT-Auth Token
Something custom that interface with the Redis queue:
Here's an example of the latter:
var SECRET_KEY = '<YOUR_LARAVEL_SECRET_KEY>';
var laravel_session_parser = {
ord: function (string) {
return string.charCodeAt(0);
},
decryptSession: function (cookie, secret) {
if (cookie) {
var session_cookie = JSON.parse(new Buffer(cookie, 'base64'));
var iv = new Buffer(session_cookie.iv, 'base64');
var value = new Buffer(session_cookie.value, 'base64');
var rijCbc = new mcrypt.MCrypt('rijndael-128', 'cbc');
rijCbc.open(secret, iv);
var decrypted = rijCbc.decrypt(value).toString();
var len = decrypted.length - 1;
var pad = laravel_session_parser.ord(decrypted.charAt(len));
return phpunserialize.unserialize(decrypted.substr(0, decrypted.length - pad));
}
return null;
},
getUidFromObj: function (obj, pattern) {
var regexp = /login_web_([a-zA-Z0-9]+)/gi;
if (pattern) {
regexp = pattern;
}
var u_id = null;
for (var key in obj) {
var matches_array = key.match(regexp);
if (matches_array && matches_array.length > 0) {
u_id = obj[matches_array[0]];
return u_id;
}
}
return u_id;
},
getRedisSession: function (s_id, cb) {
var _sessionId = 'laravel:' + s_id;
client.get(_sessionId, function (err, session) {
if (err) {
cb && cb(err);
return;
}
cb && cb(null, session);
});
},
getSessionId: function (session, _callback) {
var u_id = null,
err = null;
try {
var laravelSession = phpunserialize.unserialize(phpunserialize.unserialize(session));
u_id = laravel_session_parser.getUidFromObj(laravelSession);
} catch (err) {
_callback(err, null);
}
_callback(err, u_id);
},
ready: function (socket, _callback) {
if (typeof socket.handshake.headers.cookie === 'string') {
var cookies = cookie.parse(socket.handshake.headers.cookie);
var laravel_session = cookies.laravel_session;
var session_id = laravel_session_parser.decryptSession(laravel_session, SECRET_KEY);
laravel_session_parser.getRedisSession(session_id, function (err, session) {
if (!err && session) {
laravel_session_parser.getSessionId(session, function (err, user_id) {
if (user_id) {
_callback(null, session_id, user_id, laravel_session)
} else {
_callback(new Error('Authentication error'), null);
}
});
} else {
_callback(new Error('Authentication error'), null);
}
});
}
}
};
Now you can just have IO get an instance of the individuals session when they establish a connection to socket.io
io.on('connection', function (socket) {
laravel_session_parser.ready(socket, function(err, session_id, user_id, laravel_session) {
//log out the variables above to see what they provide
});
});
Note, I prefer to use dotenv in NodeJS to share environment variables between Laravel and Node.
Then you can do process.env.APP_KEY and you don't need to worry about sharing variables.
Also of note, that script above is not complete and is not production ready, it's just meant to be used as an example.

Why my model does not get synced?

I've written my first program with racer. It displays a simple text box manually bound to 'col.doc.prop' path. When I change the value, it does not apply to the store at server.
What causes my subscribed model not to get sync with server?
Server code:
var fs = require('fs');
var io = require('socket.io');
var racer = require('racer');
var mongo = require('racer-db-mongo');
racer.use(mongo);
racer.js({
entry: __dirname + '/client.js'
}, function(err, js) {
return fs.writeFileSync(__dirname + '/script.js', js);
});
var express = require('express');
var server = express.createServer();
server.use(express.static(__dirname));
server.get('/', function(req, res)
{
var model = store.createModel();
model.subscribe('col.doc', function(err, doc)
{
var prop = doc.get('prop');
if (!prop)
{
doc.set('prop', 123);
store.flush();
}
model.ref('_doc', doc);
model.bundle(function(bundle)
{
var client = require('fs').readFileSync('./client.html', 'utf-8');
client = client.replace('_init_', bundle.toString());
res.send(client);
});
});
});
var store = racer.createStore(
{
listen: server,
db:
{
type: 'Mongo',
uri: 'mongodb://localhost/racerdb'
}
});
store.set('col.doc.prop', 123);
store.flush();
server.listen(3001);
Client code:
useRacer = function()
{
var socket = io.connect('http://localhost:3001');
var racer = require('racer');
process.nextTick(function() {
racer.init(this.init, socket);
return delete this.init;
});
racer.on('ready', function(model)
{
addListener = document.addEventListener ? function(el, type, listener) {
return el.addEventListener(type, listener, false);
} : function(el, type, listener) {
return el.attachEvent('on' + type, function(e) {
return listener(e || event);
});
};
var element = document.getElementById('prop');
var listener = function()
{
var val = element.value;
model.set('col.doc.prop', val);
};
addListener(element, 'keyup', listener);
var upgrade = function(id, value)
{
if (model.connected)
{
var prop = model.get('col.doc.prop');
element.value = prop;
}
else
model.socket.socket.connect();
};
model.on('connectionStatus', upgrade);
model.on('set', 'con.*', upgrade);
});
};
The problem solved by changing some lines of the client code:
model.set('col.doc.prop', val) ==> model.set('_doc.prop', val)
model.get('col.doc.prop') ==> model.get('_doc.prop')
model.on('set', 'con.', upgrade) ==> model.on('set', '', upgrade)

Resources