Multi threading in Node.js? - javascript

I am implementing socket.io in node.js for a Windows Azure project. I have to send data to all the connected clients at regular intervals.
I am new to node.js but I guess multi-threading is not possible. The purpose of socket.io is to support real-time applications, so is there any way that I can send data continuously to all my connected clients at regular intervals and also process whatever data the clients send to the socket.io server simultaneously?
EDIT:
This is roughly my socket.io implementation
var io = require('socket.io').listen(80);
io.sockets.on('connection', function (socket) {
socket.emit('first', "connected");
socket.on('clientData', function (data) {
//processing the data
});
});
function requestQueue() {
// some processing
io.sockets.emit('broadcast', recordsQueue);
// should go to sleep for a time period
}
Essentially I want the requestQueue method to be running continuously like a thread, which will emit data to connected clients at particular intervals. And also if the client sends any data to "clientData" event, then I should be able to receive the data and process it.
Any idea on how I can do it?
Thanks
My solution:
var io = require('socket.io').listen(80);
io.sockets.on('connection', function (socket) {
socket.emit('first', "connected");
socket.on('clientData', function (data) {
//processing the data
});
});
function requestQueue() {
var sleepTime = 0;
// calcuate sleepTime
io.sockets.emit('broadcast', recordsQueue);
// should go to sleep for a time period
if(sleepTime !=0)
setTimeout(function () { requestQueue() }, sleepTime);
}

As others have suggested, you can achieve this by using the setInterval or setTimeout functions to periodically emit data to connected clients. Although everything runs within the same controlling thread, all of the I/O is done asynchronously so your application will still be responsive. IE, any data received while the timer is running will be queued up and processed after the timer function returns.
See Timers in the node.js manual for more information.
On a side note, you will want to have your node.js application focus on processing asynchronous I/O in near real-time as that is the strength of node.js. If you need to do any heavy computations then you will want to offload that to another thread/process somehow, by simply making an async request for the result.

You are right, node is single threaded. But it makes heavy use of events.
The strategy you should go for is to listen for events on the connections, to retrieve data, and when you wish to send data back you do it because another event has been emitted.
If you take a look at the examples on the socket.io frontpage, you will see how they use events to start processing the streams. The on(eventName, function) method is how you listen for an event in NodeJS.
If you wish to do something based on timing (generally a bad idea), take a look at the setInterval method.
Server
var io = require('socket.io').listen(80);
io.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
Client
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost');
socket.on('news', function (data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
});
</script>

There is also a Node.js library for doing threads: node-webworker-threads
https://github.com/audreyt/node-webworker-threads
This basically implements the Web Worker browser API for node.js.
Note that this does not align with node.js's philosophy of single threadedness, but it's there if you need it.

Multi threading in Node.js?
Yes ..it is possible in nodejs using npm module 'java4node', it this package a method is
.multiThreading(tasks , callbacks)
This Function is use for perform multithreading in java script manner
for using this module
link: https://www.npmjs.com/package/java4node
run commend
npm install java4node
var java = require('java4node')
java.multiThreading({
one: function(callback,parameters) {
console.log("function one is running independently");
callback()
},
two: function(callback,parameters) {
console.log("function two is running independently");
callback()
},
three: function(callback,parameters) {
console.log("function three is running independently");
callback()
}
}, function(err, results) {
callback(err, results)
});

The logic you define inside the setInterval etc. won't be working in a separate thread and eventually blocking the main. Let's say there are 1000 users and you called the setTimeout etc. for 1000 times, eventually they will be running and spending that precious time. Only the final IO operations are none-blocking!
You may consider investigating nodeJX for multithreading in node.js

Related

How to create sockets that particular to user and disposable on Socket.Io

I write a Node.Js app and I use Socket.Io as the data transfer system, so requests should be particular to per user. How can I make this?
My actual code;
node:
io.on('connection', (socket) => {
socket.on('loginP', data => {
console.log(data);
})
})
js:
var socket = io('',{forceNew : false});
$("#loginbutton").click(function() {
var sessionInfo = {
name : $("#login input[name='username']").val(),
pass : $("#login input[name='pass']").val()
}
socket.emit("loginP", sessionInfo)
})
It returns one more data for per request and this is a problem for me. Can I make this on Socket.Io or should I use another module, and If I should, which module?
If I understand your question correctly (It's possible I don't), you want to have just one connection from each user's browser to your nodejs program.
On the nodejs side, your io.on('connection'...) event fires with each new incoming user connection, and gives you the socket for that specific connection. So, keep track of your sockets; you'll have one socket per user.
On the browser side, you should build your code to ensure it only calls
var socket = io(path, ...);
once for each path (your path is ''). TheforceNew option is for situations where you have multiple paths from one program.

How can I connect a node.js server page to my sockets server as though it were a client?

I've seen many similar questions here, like this one about connecting servers to sockets, however, that doesn't seem to be working.
My goal is to have one of my server pages occasionally emit an "advance" event to all of the connected clients. My sockets server listener (sockets.js) looks like this
io.on('connection', function (socket) {
socket.on('advance', function () {
console.log('advancing clients');
io.emit('advance');
});
});
and my other server page (queue.js) has this code
var socket = require('socket.io-client');
socket.connect('localhost:5000');
socket.on('connect', function () {
socket.emit('advance');
});
I have also tried
var socket = require('socket.io-client');
socket.connect('localhost:5000');
socket.emit('advance');
Both of those were in the other question I linked, however both of those failed. In the case of the first example, I received the error
socket.on is not a function
and on the second
socket.emit is not a function
it would seem that socket.connect worked, however, socket.on and socket.emit both failed. The idea is that queue.js will emit an event to all the clients, so they know to request the next song from the server.
As bonus points, I happen to be using passport.socketio to authenticate my users (though I don't seem to be getting the "ioAuthFail" message that would normally occur when a user attempts to connect and is not authenticated).
for what it's worth, my socket authentication code looks like
io.use(passportSocketIo.authorize({
//cookieParser:
key:'user',
secret:'secret',
store:new MongoStore({mongooseConnection:mongoose.connection}),
success:onAuthorizeSuccess,
fail:function(){console.log('ioAuthFail')}
}));
If there's a better way to advance the clients than using socket.io, i would also accept that, but for now it seems like this is the best way for me, assuming I can get this working.
EDIT
as mentioned through comments, changing my code to
var io = require('socket.io-client');
socket = io.connect('localhost:5000');
socket.on('connect', function () {
socket.emit('advance');
});
socket.emit('advance');
doesn't break it, but it doesn't work, either.

Emit an event with node.js socket client to sails.js (0.11.x) [duplicate]

This question already has an answer here:
Emitting a message in sails v0.11 (client-side)
(1 answer)
Closed 6 years ago.
The server: sails.js (0.11.x) is the server
The client: A node.js script with sails.io#0.11.5 and socket.io-client#1.3.5
Big picture: I have, or will have, a farm of node.js scripts that connect to the sails.js server and will perform various tasks.
Immediate Goal: I want to emit an event during a socket connection from client->server such as:
socket.emit('got_job', job.id);
Why? If this is possible I can create various event handlers on the server side in one controller (or controller + service) and keep my code clean while managing a set of stateful transactions between client/server endpoints for supporting this script farm.
The documentation: This is how one goes about using socket.io-client for sails.js this per sails docs: https://github.com/balderdashy/sails.io.js?files=1#for-nodejs
I haven't much code to share other than what's in that link, but I'll paste it here just in case:
var socketIOClient = require('socket.io-client');
var sailsIOClient = require('sails.io.js');
// Instantiate the socket client (`io`)
// (for now, you must explicitly pass in the socket.io client when using this library from Node.js)
var io = sailsIOClient(socketIOClient);
// Set some options:
// (you have to specify the host and port of the Sails backend when using this library from Node.js)
io.sails.url = 'http://localhost:1337';
// ...
// Send a GET request to `http://localhost:1337/hello`:
io.socket.get('/hello', function serverResponded (body, JWR) {
// body === JWR.body
console.log('Sails responded with: ', body);
console.log('with headers: ', JWR.headers);
console.log('and with status code: ', JWR.statusCode);
// When you are finished with `io.socket`, or any other sockets you connect manually,
// you should make sure and disconnect them, e.g.:
io.socket.disconnect();
// (note that there is no callback argument to the `.disconnect` method)
});
What I have looked into: I've drilled into various levels of these objects and I can't seem to find anything exposed to use. And simply trying io.socket.emit() as it doesn't exist. But io.socket.get() and io.socket.post(), etc work fine.
console.log(socketIOClient);
console.log(sailsIOClient);
console.log(io);
console.log(io.socket._raw);
console.log(io.sails);
Thanks, and I'll try to update this as needed for clarification.
UPDATE:
Misc Server Info.:
I'm using nginx on port 443, with SSL termination, pointing to 4 (and
soon more) sails.js instances on separate ports (3000-3003).
I'm also using Redis for sessions and sockets.
You're close:
Your io.socket.get call is kind of like a rest api call. You'd need a sails controller bound to a get request on the url '/hello',
//client
io.socket.get('/hello', function serverResponded (body, JWR) {
//this is the response from the server, not a socket event handler
console.dir(body);//{message:"hello"}
});
in
config/routes.js:
{
'get /hello':'MyController.hello'
}
//controllers/MyController
{
hello:function(req,res){
res.json({message:"hello"});
}
}
The method you're looking for is, io.socket.on('eventName');
Here's an example:
//client
io.socket.get('/hello', function serverResponded (body, JWR) {
//all we're doing now is subscribing to a room
console.dir(body);
});
io.socket.on('anevent',function(message){
console.dir(message);
});
in
config/routes.js:
{
'get /hello':'MyController.hello'
}
//controllers/MyController
{
hello:function(req,res){
sails.sockets.join(req.socket,'myroom');
res.json({message:'youve subscribed to a room'});
}
}
What we've effectively done is, setup our socket to be part of a "room", which is basically an event namespace. Then, some other controller only has to do this:
sails.sockets.broadcast('myroom','anevent',{message:'socket event!'});
After this call is made, you would receive the message in the callback of io.socket.on('anevent').

Where is a good place to put socket.io logic in sails.js

where is a good place to put my logic if I want to use sails.io? Is config/bootstrap.js a good place to put it? Or is there some other file I can create somewhere else?
This code below works:
// config/bootstrap.js
module.exports.bootstrap = function (cb) {
sails.io.sockets.on('connection', function(socket) {
console.log("Got a connected client");
});
cb();
};
It doesn't support this until 0.9.4.
step 1. Get the latest version of sails.js
step 2. Generate sails with the the cli
step 3. See config/sockets.js, customize onConnect function, see below:
module.exports.sockets = {
// This custom onConnect function will be run each time AFTER a new socket connects
// (To control whether a socket is allowed to connect, check out `authorization` config.)
// Keep in mind that Sails' RESTful simulation for sockets
// mixes in socket.io events for your routes and blueprints automatically.
onConnect: function(session, socket) {
// By default: do nothing
// This is a good place to subscribe a new socket to a room, inform other users that
// someone new has come online, or any other custom socket.io logic
console.log("Got a connected client");
},
...
For logic processing, you can put it in the following places:
Controller: if a request should trigger a real-time event
Service: if you want :) but I think Controller is referred
/config/socket.js onConnect(), onDisconnect(): If you want to add or remove the connected socket to/from some rooms, or some initial socket setup, etc.
/policies/sessionAuth.js: for some real-time authen logic
Other places...
Beside, you should consider the resourceful-pubsub feature which may help you save a lot of effort on implementing real-time process with socket. I found that it's very cool :)

Socket.IO Scoping Issue (Node.JS)

I am working on a node.js project that I am leveraging Socket.IO in, and am having an issue getting my head around a scoping issue. Here is what I am trying to do:
var io = require('socket.io').listen(80);
session_manager = require('./includes/session_manager');
// client joins the socket server
io.sockets.on('connection', function(client) {
client.on('X.Session.join', function(session_id, client) {
session_manager.joinSession(session_id, function(err, session) {
// do whatever
});
});
// BRING IN MORE LISTENERS/EMITTERS?
require('someModuleIBuild');
});
As you can see I am basically setting up the initial connection, joining a session via a managing class (so I know who to emit to for which session) and then I am trying to dynamically bring in some custom stuff that ALSO is going to be emitting and listening via the socket connection.
So how do I reference this current connection from within the confines of my custom modules? All the examples I have seen have all the "on" and "emit" functions in one file, which seems like it could get out of control pretty quickly.
I am possibly over-thinking/over-complicating this (this is my first node.js project, first socket-based project, first mostly-javascript project....etc) but any help would be appreciated.
create your modules like this and you can pass the client into the module
module.exports = function(client) {
client.on("whatever", function () {
});
client.on("whenever", function (data) {
});
};
and then do the require like this
require('someModuleIBuild')(client);

Categories