socket.io callback function not working - javascript

I used to use socket.io emit callback like following:
client:
mysocket.emit('helloword', 'helloword', function(param){
console.log(param);
});
server:
var server = require('http').Server(app);
var sserver = io(server);
sserver.on('connection', function(socket){
console.log('connection');
socket.on('helloword', function(message, callback){
console.log(message);
console.log(callback+'');
console.log('arguments', arguments);
callback('helloword');
})
});
server.listen(config.port);
I'm using angular-socket-io as a wrapper for socket.io-client. My service is simple as:
'use strict';
angular.module('core').factory('mysocket', function(socketFactory){
return socketFactory();
});
server output:
connection
helloword
function (){
// prevent double callbacks
if (sent) return;
var args = Array.prototype.slice.call(arguments);
debug('sending ack %j', args);
var type = hasBin(args) ? parser.BINARY_ACK : parser.ACK;
self.packet({
id: id,
type: type,
data: args
});
}
arguments { '0': 'helloword', '1': [Function] }
My client console:
My question:
Why my callback is not firing ?

The function socket.on(event, callback) will listen for an event from the client and then run the callback when the event is triggered. In your case, when it hears 'helloword' it will run the callback function that you defined as the second parameter: function(message, callback). Your server log output shows that, actually, all of the console.log calls in your callback are being run.

To see what's going on client side try set the localStorage.debug = '*'
See this for more info: http://socket.io/docs/migrating-from-0-9/#log-differences (assuming you use socketio 1.0+)

Related

How a function is getting called with correct request & response objects?

I have a piece of code:
var http = require('http');
function createApplication() {
let app = function(req,res,next) {
console.log("hello")
};
return app;
}
app = createApplication();
app.listen = function listen() {
var server = http.createServer(this);
return server.listen.apply(server, arguments);
};
app.listen(3000, () => console.log('Example app listening on port 3000!'))
Nothing fancy here. But when I run this code and go to localhost:3000, I can see hello is getting printed. I'm not sure how this function is getting called at all. Also, the function receives the req & res objects as well. Not sure whats happening here.
http.createServer() has a couple optional arguments. One being requestListener which is
https://nodejs.org/api/http.html#http_http_createserver_options_requestlistener
The requestListener is a function which is automatically added to the
'request' event.
Since you call your listen() like so app.listen(), this inside that function is going to be a reference to the function you made and returned in createApplication. So you are basically doing:
http.createServer(function(req,res,next) {
console.log("hello")
});
Hence your function is added as a callback for any request, and thus why any request you make will create a console log of hello.
If you want an equivalent more straight forward example
var http = require('http');
var server = http.createServer();
server.on('request',function(req,res,next) {
//callback anytime a request is made
console.log("hello")
});
server.listen(3000);

socket.io get socket inside a callback

I'm using socket.io for node.js. If you add an event handler like this:
io = require('socket.io')(http);
io.on('connect',function(socket){
socket.on('some event',function(arg1,arg2){
/// using socket to emit events for example
}
}
Then I can access socket inside the callback for the 'some event'
However what if I use it like this
io = require('socket.io')(http);
io.on('connect',function){
socket.on('some event',myfunction);
}
function myFunction(arg1,arg2)
{
//I want to use calling socket here.
}
How do I access socket in the later case?
I need the socket to get the socket.id so I can know who called this event.
Thanks
Well, if I understand what you want to do, you can simply:
io = require('socket.io')(http);
io.on('connect',function){
socket.on('some event',myfunction);
}
function myFunction(arg1,arg2)
{
var socketId = this.id; //here you go, you can refer the socket with "this"
}
This is what I usually do to keep the code clean:
var on_potato = function(potatoData){
var socket = this;
var id = socket.id;
//use potatoData and socket here
};
var on_tomato = function(tomatoData){
var socket = this;
var id = socket.id;
//use tomatoData and socket here
};
var handleClientConnection = function (client) {
client.on('potato', on_potato);
client.on('tomato', on_tomato);
};
io.on('connection', handleClientConnection)
Alright, so after discussing this a potential solution is to just invoke your named function from within the anoymous callback function passed to the on method.
io.on('connect', function(socket){
socket.on('someEvent', function(username, date){
// If you emitted an object, you'll need to parse the incoming data. So say
// You emitted {username: 'SomeName', date: 'SomeDate' }
// You could just pass data.username and data.date directly
// or put them into local variables, like:
//var username = data.username, date = data.date;
// Invoke your named function here and you can pass
// whatever you want to it, along with the socket
myFunction(username, date, socket)
})
})
myFunction(username, date, socket){
// Do whatever you're doing with the passed paramaters
}
I've used Lodash's partial function quite often to solve problems like this (Underscore has one as well, which does the same thing). Basically what it does is create a new function that has some of the original function's arguments filled in. So what you would do is something like this:
io = require('socket.io')(http);
io.on('connect', function(socket) {
socket.on('some event', _.partial(myfunction, socket));
});
function myFunction(socket, ...args) {
// whatever you wanna do
}
Then, when the new curried function is returned from the partial execution, it has socket prefilled as the first param and you can use it how you'd like.
Just a note that the ...args is just a placeholder for whatever you want to put there. Also, I'm not sure if socket.io passes anything into the function on firing the callback, which may affect the placement of the arguments into the curried function. If socket, shouldn't be the first argument, you can make it the second thusly:
io = require('socket.io')(http);
io.on('connect', function(socket)){
socket.on('some event', _.partial(myfunction, _, socket));
}
function myFunction(arg1, socket, ...args) {
// whatever you wanna do
}

Node JS push server send/receive

I am trying to set up a node js server to do push notifications to my browser app. I have a basic example working, but I am wondering how to send data up to the server from the client on handshake.
I Need to send to the server something like a user id, so when a notification comes in for them, it can be routed back to the user.
my server looks something like this
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, fs = require('fs');
app.listen(8000);
function handler ( req, res ) {
res.writeHead( 200 );
res.end('node working');
};
io.sockets.on( 'connection', function ( socket ) {
socket.volatile.emit( 'notification' , "blah" );
});
and my client looks something like this
var socket = io.connect('http://localhost:8000');
socket.on('notification', function (data) {
//prints data here
});
In socket.io, the emit is essentially like any other event handler (e.g. jQuery's .on('click'...)); you declare the event and send the data. On the server, you add the .on('event', ...) to catch the request and process it.
The socket.io front page shows this example for the 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);
});
});
And this for the 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>
It sounds like the part you're looking for is the socket.emit portion.
I have done this sort of thing in the past by setting a cookie on the client (which you're probably doing anyway), and then using socket.io's authorization event. You can use this event to decide whether to even accept the socket connection to the user in the first place.
io.configure(function () {
io.set('authorization', function (handshakeData, callback) {
var cookie = handshakeData.headers.cookie;
// parse the cookie to get user data...
// second argument to the callback decides whether to authorize the client
callback(null, true);
});
});
See more documentation here: https://github.com/LearnBoost/socket.io/wiki/Authorizing
Note that handshakeData.headers.cookie is just a string literal representation of the cookie, so you'll have to do your own parsing.

JavaScript callbacks function object

i try to learn node.js and try to create a new TCP Server connection. The code
var server = require('net').createServer(function(socket) {
console.log('new connection');
socket.setEncoding('utf8');
socket.write("Hello! You can start typing. Type 'quit' to exit.\n");
socket.on('data', function(data) {
console.log('got:', data.toString());
if (data.trim().toLowerCase() === 'quit') {
socket.write('Bye bye!');
return socket.end();
}
socket.write(data);
});
socket.on('end', function() {
console.log('Client connection ended');
});
}).listen(4001);
look at the callback function, after then, they call listen method. What is this for kind of object.
What it basically says is:
function myHandler(socket) {
// everything up to socket.on('end')
}
var server = require('net').createServer(myHandler);
server.listen(4001);
So it's just creating a socket server with a handler function, and then make the server listen to port 4001.

sending objects to a callback function as a parameter- nodejs

I am implementing a http server for some project.
I have an HttpServer object that I created that contains in it a server (net module)
this server contains allot of info, and i want to pass it as parameter to the callback functions. like you would do with "setTimeout"
var time=setTimeout(function(**a**){do somthing}, 2000, **someObject**);
I tried doing something like that in my code but it does not recognize the parameter I passed as an object
var net = require('net');
function HttpServer(port){
this.port=port;
}
HttpServer.prototype.start = function (){
console.log("starting the server");
this.server = net.createServer(function (socket,server) {
console.log("my port is: "+server.port)
socket.on('data',function(dat){ });
},this);
//i am trying to send to the createserver callback function
//the parameter 'this' that actually is an HttpServer
//and the callback function secives it as 'server'
//when i run the program i get an error that server is
//undefiend and therefor does not have a member port
this.server.listen(this.port);
}
var httpserver= new HttpServer(4444);
httpserver.start();
Why it does not recognize the parameter sent?
var net = require('net');
function HttpServer(port){
this.port=port;
}
HttpServer.prototype.start = function (){
console.log("starting the server");
var that = this; //Store this to that variable
this.server = net.createServer(function (socket, server) {
console.log('Server port is: ' + that.port); // Use that in an anonymous function
socket.on('data',function(dat){ });
});
this.server.listen(this.port);
}
var httpserver= new HttpServer(4444);
httpserver.start();

Categories