I've the following Server Side Code:
var express = require('express')
, http = require('http')
, routes = require('./routes')
, io = require('socket.io')
, factory = require('./serverfactory.js');
var app = express();
var server = app.listen(3000);
io = io.listen(server);
io.sockets.on('connection',function(socket){
console.log('new user');
socket.emit('hail','mysimplemsg');
socket.on('customevent',function(msg){
console.log(msg);
});
});
//var app = module.exports = express.createServer();
// Configuration
app.configure(function(){
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});
app.configure('development', function(){
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});
app.configure('production', function(){
app.use(express.errorHandler());
});
// Routes
app.get('/', routes.index);
And this is the client side :
var socket = io.connect('http://localhost:3000');
socket.emit('customevent','work');
socket.on('hail',function(msg){
console.log(msg);
});
I am expecting that my git console outputs new user (which it does) then it should output work (which it does not) then i get a msg in my browser console mysimplemsg (which it does not).
Whats going on why the event at server side that is customevent is not called and why the event at the client side that is hail is not called ?
I believe the issue is that you are emitting customevent from the client before you are connected. Try adding a connect handler and moving your client side emit into it:
var socket = io.connect('http://localhost:3000');
socket.on('hail',function(msg){
console.log(msg);
});
socket.on('connect',function(){
console.log('connected to socket.io server');
socket.emit('customevent','work');
});
If the connect handler is not hit then verify that you are referencing the client side socket.io javascript library correctly (jade syntax):
script(type='text/javascript',src='/socket.io/socket.io.js')
Finally figured it out.
It was working fine on opera but not on chrome and firefox. I found this link in which the guy says to insert this code snippet on the server side.
io.configure('development', function(){
io.set('transports', ['xhr-polling']);
});
It's working fine now.
Related
I have an electronic board, which collects data from sensors and I hope to send it to an web service, which then does some processing and sends the results to an website, when URL is entered. I use multiple ports for this. One port listens for UDP connection and other port is for HTTP. The code works fine on my local machine. Here is the code
var net = require('net')
,dgram = require('dgram')
,express = require('express')
,io = require('socket.io')
,routes = require('./routes')
,http = require('http')
,fs = require('fs');
var app = module.exports = express.createServer();
var HOST = '192.168.0.132'
var PORT = 1337
var datarr = []
app.configure(function(){
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.set('view options', {layout:false, pretty:true});
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});
app.configure('development', function(){
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});
app.configure('production', function(){
app.use(express.errorHandler());
});
//ROUTES
app.get('/',routes.index);
//UDP Server
var decoder = new (require('string_decoder').StringDecoder)('utf-8')
var buffer = '';
var server = dgram.createSocket('udp4');
server.on('listening',function() {
console.log('Listening');
});
server.on('message', function(data,rinfo) {
console.log(decoder.write(data));
io.sockets.emit('data',decoder.write(data));
});
server.on('close', function(data) {
console.log('closed');
});
server.bind(1337,'192.168.0.132');
//UDP server ends
var io=require('socket.io').listen(app);
app.listen(1185);
io.sockets.on('connection',function (socket) {
console.log('Hello Got a connection');
});
console.log("server listening");
I know it can't be hosted on heroku, because it allows only one port.
What are my options?
1)According to some answers on this website, websockets. But i have no idea on how to set up websocket between udp and http server. Any links to websites/github would be very helful.
2)Hosting services which allow multiple ports. Are there any which provide this service? Links to documentations will be appreciated.
Thanks in advance.
You can do some thing like this
var port = process.env.PORT || 1185;
and then use this port variable as
app.listen(port);
every time when you need to run on different port just use
PORT = node app.js
I am using current versions of all things node.js, express.js, socket.io etc ... I am trying to connect to a server who's sole purpose in life is just spew text and in turn send it to web client connected via socket.io. The text is nothing more character strings with standard line endings and the max data rate is something on the order of 1024bytes/sec. My code, the core bits, is something like this
var express = require('express')
, app = express()
, routes = require('./routes')
, user = require('./routes/user')
, server = require('http').createServer(app)
, io = require('socket.io').listen(server)
, path = require('path')
, dataSourcePort = 5000
, host = "10.0.1.32"
, dataStream = require('net').createConnection(dataSourcePort, host);
dataStream.setEncoding('utf8');
io.sockets.on('connection', function (socket) {
dataStream.on('data',function(data){
socket.emit("stuff",data);
});
});
app.configure(function(){
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
});
app.configure('development', function(){
app.use(express.errorHandler());
});
app.get('/', routes.index);
app.get('/users', user.list);
server.listen(app.get('port'), function(){
console.log("Express server listening on port " + app.get('port'));
});
This works all fine and dandy but, every once in a while it just hangs, as in the data stops going out to the clients. I assume a buffer gets stuffed somewhere along the line but, not sure. Is there a better way to do this and avoid the stuffing part?
The main issue I see is that you never unbind your data handler, so as people connect and disconnect, you will accumulate data listeners and memory usage, and waste resources trying to send data to disconnected sockets.
io.sockets.on('connection', function (socket) {
function ondata(data){
socket.emit("stuff",data);
}
function ondisconnect(){
dataStream.off('data', ondata);
socket.off('disconnect', ondisconnect);
}
dataStream.on('data', ondata);
socket.on('disconnect', ondisconnect);
});
I am just trying to send a simple message from client to server on button Click.
Edit:
When my index.jade loads I use the following code and for creating the socket.io object and then forward it to my Menu_Contoller which in turn assigns the socket object to the Menu_Model.Then whenever the function SendOptionSelectedToServer of Menu_Model.js is called i use the socket object to of Menu_Model.The values in this function are correct.Just don't know why it is not emitting.
index.jade
script(src = '/socket.io/socket.io.js')
script(src = '/javascripts/Menu_Controller.js')
script(src = '/javascripts/Menu_Model.js')
script
var socket = io.connect('http://localhost:3000');
socket.emit('GameType','chutia');
var Menu_Control = Object.create(Menu_Controller);
Menu_Control.Init(socket);
Menu_Controller.js
var Menu_Controller = {
Model : null,
Init:function(socket)
{
this.Model = Object.create(Menu_Model);
this.Model.Init(socket,this);
},
SendOptionSelectedToServer:function(option) <-- called from a view menu which we don't have to care about because value in 'option' are correct.
{
this.Model.SendOptionSelectedToServer(option);
}
};
Menu_Model.js
var Menu_Model = {
Socket : null,
Controller : null,
Init:function(sock,controllerRef)
{
this.Socket = sock;
this.Controller = controllerRef;
},
SendOptionSelectedToServer:function(option)
{
this.Socket.emit(option.type,option.ghostName); <-- this line.
}
};
And here's my complete server side code in app.js.
var express = require('express')
, http = require('http')
, routes = require('./routes')
, io = require('socket.io')
, factory = require('./serverfactory.js');
var app = express();
var server = app.listen(3000);
io = io.listen(server);
io.sockets.on('connection',function(socket){
console.log('new user'); <-- this is printed in the log.
socket.on('GameType',function(msg){
console.log(msg); <-- but this is not.
});
});
//var app = module.exports = express.createServer();
// Configuration
app.configure(function(){
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});
app.configure('development', function(){
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});
app.configure('production', function(){
app.use(express.errorHandler());
});
// Routes
app.get('/', routes.index);
When a new connection occurs it writes new user in the log.But when a call is made using emit from the client side it doesn't write any msg in the console.I've already checked the params at the client side and they are correct. the option.type at the client side will contain GameType.
Why it is not calling the event on the client side ?
i m creating chat application, using nodejs (0.8.15), express (>3.0) framework and mongodb for register users.
var express = require('express')
, http = require('http')
, path = require('path')
, io = require('socket.io');
var app = express()
, server = http.createServer(app)
, io = io.listen(server);
app.configure(function() {
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.cookieParser('secret'));
app.use(express.session({cookie: {maxAge: 60000*100}}));
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
});
app.configure('development', function() {
app.use(express.errorHandler());
});
app.get('/chat', function(req, res) {
res.render('chat');
});
server.listen(app.get('port'), function() {
console.log("Express server listening on port " + app.get('port'));
});
io.sockets.on('connection', function (socket) {
socket.on('start-chat', function() {
// here i need to know req and res
// for example, i need to write:
// socket.username = req.session.username;
});
});
Q: How to get res and req objects to work with them when chatting like on code above? or am i going wrong way of creating chat with user auth?
thank you!
EDITED: answer is here
http://www.danielbaulig.de/socket-ioexpress/
You need to use authorization.
var socketIO = require('socket.io').listen(port);
socketIO.set('authorization', function(handshakeData, cb) {
//use handshakeData to authorize this connection
//Node.js style "cb". ie: if auth is not successful, then cb('Not Successful');
//else cb(null, true); //2nd param "true" matters, i guess!!
});
socketIO.on('connection', function (socket) {
//do your usual stuff here
});
You cannot get res and req objects in a socket.io handler, as they simply do not exist - socket.io is not normal http.
Instead, what you can do is authenticate users and assign them a session auth token (a key that identifies that they're logged in and who they are).
Then the client can send the auth token along with every socket.io message, and the server-side handler can just check the validity of the key in the database:
io.sockets.on('connection', function (socket) {
socket.on('start-chat', function(message) {
if (message.auth_token)
//Verify the auth_token with the database of your choice here!
else
//Return an error message "Not Authenticated"
});
on socket.io v1.0 and above you can get the req object like this
var req = socket.request;
var res = req.res;
I'm having trouble connecting to socket.io with the client being located on a different port, on the same machine.
The client is part of a site run on Apache (port 80) and Nodejs is being run on 8585.
Any idea what I'm doing wrong here?
On the client side, I get the 'Unable to connect Socket.IO' message, with no reason.
Server:
var express = require('express'),
connect = require('connect'),
RedisStore = require('connect-redis')(express),
io = require('socket.io').listen(app),
routes = require('./routes'),
request = require('request');
var app = module.exports = express.createServer();
// Configuration
app.configure(function(){
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.session({ secret: "secret", store: new RedisStore}));
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});
app.configure('development', function(){
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});
app.configure('production', function(){
app.use(express.errorHandler());
});
io.set('authorization', function(handshakeData, callback) {
console.log('authorization');
callback(null, true);
});
//Socket IO connection
io.sockets.on('connection', function (socket) {
var session = socket.handshake.session;
console.log(session);
});
app.listen(8585);
console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);
Client: (run from a site on apache and different domain, but same server).
var sio = io.connect('http://localhost:8585');
sio.socket.on('error', function (reason){
console.error('Unable to connect Socket.IO', reason);
});
sio.on('connect', function (){
console.error('successfully established a working connection \o/');
});
Thank you!
Unless you're running the browser on the same computer as the server, "localhost" in your code will refer to the computer running the browser, not the server. DNS lookups for localhost always resolve to the computer doing the lookup. And even if you're accessing the site on the same computer as the server, unless you're accessing it as "localhost", the browser's security policies will prevent you from talking to localhost.