I am making simple websocket demo (ws) with expressjs
Server Side code
var WebSocketServer = require('ws').Server
, http = require('http')
, express = require('express')
, app = express();
app.configure('development', function() {
app.use(express.json());
app.use(express.urlencoded());
app.use(app.router);
});
app.set('view engine', 'ejs');
app.set('view options', {layout: false});
var server = http.createServer(app);
server.listen(2678);
app.get('/', function(req, res) {
res.redirect('views/index.html');
});
var wss = new WebSocketServer({server: server});
wss.on('connection', function(ws) {
console.log("Connection Open");
ws.on('message', function(e) {
console.log(e); // Can't get message here
});
ws.on('close', function() {
console.log('stopping client interval');
});
});
And my client side (Browser)
ws = new WebSocket('ws://localhost:2678?uid=123&token=abc123');
ws.onopen = function() {
console.log('Connection Open');
console.log('readyState:' + ws.readyState); // readyState:1
ws.send("Test msg");
console.log("sent!");
};
Problem :
When I execute above code I can get message "Connection Open" Message on both side. But ws.send("Test msg") not working on client side. I can't emit data neither client side nor serverside. I found lots of question on Stack Overflow. But I can't found proper solution for that.
And When I close browser after 2-3 minute I got following message in server side.
Test msg
stopping client interval
I have refereed following links. But they are not working for me.
Link1
Link2
Related
I have a node app that should receive request from another app through a HTTP GET request /api/users?data=68 and display the data in real time.I have api/users route that handle incoming HTTP request. To start with i have node app that works with socket.io But now i want to handle Http request.Here is my code
var express = require('express');
var app = express();
var server = require('http').Server(app);
var io = require('socket.io')(server);
var port = process.env.PORT || 8080
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
var router = express.Router();
router.get('/api/users', function(req, res) {
var query = req.param('data');
io.emit("chat message","some msg");
});
io.on('connection', function(socket){
console.log('client connected');
socket.on('pass data from HTTP request to the view', function(data){
console.log(data);
});
});
app.use(router);
server.listen(port)
Client.js
var socket = io();
socket.on('chat message', function (message) {
//socket.emit('chat message', { my: 'world' });
console.log('received ');
});
How do i pass data from /api/users/ route to socket connection?Thank you in adavance.
If you want to send the data to all socket.io connected clients, you can do:
io.emit("someMsg", someData);
If you want to send only to only a specific socket.io connection, then you need to be able to get that particular socket which you can do via a socket.id or some other way you keep track of which socket is which.
I am receiving a 404 when trying to resolve '/socket.io/socket.io.js' from my Node server. I can't determine why.
My server configuration looks like this:
var express = require('express')
, engine = require('ejs-locals')
, app = express()
, http = require('http')
, server = http.createServer(app)
, io = require('socket.io').listen(server);
// use ejs-locals for all ejs templates:
app.engine('ejs', engine);
app.set('views',__dirname + '/views');
app.set('view engine', 'ejs'); // so you can render('index')
app.use(express.static(__dirname + '/public'));
//define routes
...
app.listen(3000);
//socket io
io.sockets.on('connection', function (socket) {
socket.on('set nickname', function (name) {
socket.set('nickname', name, function () {
socket.emit('ready');
});
});
socket.on('msg', function () {
socket.get('nickname', function (err, name) {
console.log('Chat message by ', name);
});
});
});
At the client I have this:
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost:3000');
socket.on('news', function (data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
});
</script>
I am testing this locally (port: 3000). The Socket code is basically ripped off of the socket.io example to get something working. I have reviewed other posts and can't seem to find where I'm going wrong. Can someone help?
Thanks
Got it!
The HTTP server needs to be listing on the port (3000 in this case.) I then removed the app.listen(3000) as the address will already be in use and is not needed.
Thanks!
var express = require('express')
, engine = require('ejs-locals')
, app = express()
, http = require('http')
, server = http.createServer(app).listen(3000)
, io = require('socket.io').listen(server);
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.
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 buils small application in which I use socket.io and expressjs
Server side
var express = require('express'),
sio = require('socket.io');
var app = express.createServer();
app.configure('development', function(){
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.static(__dirname + '/'));
app.set('views', __dirname + '/views');
app.use(express.errorHandler({dumpExceptions: true, showStack: true}));
app.use(app.router);
});
app.listen(4000);
var io = sio.listen(app);
app.get('/', function (req, res) {
res.redirect('index.html');
});
io.sockets.on('connection', function (socket) {
app.post('/mysegment',function(req,res){
var userData = req.body;
socket.emit('sendUser', userData);
res.send("yes I got that segment");
});
socket.on('getUser',function(msg){
console.log("Yes Socket work Properly "+msg);
});
});
And index.html
var socket = io.connect();
socket.on('connect', function () {
console.log("client connection done.....");
});
socket.on('sendUser', function (data) {
alert("On send user");
socket.emit('getUser',"Hello");
});
This demo work perfectly
But When I refresh page
And send post request to "/mysegment" that I time socket does not work properly.
I do not get message on my console "Yes socket work properly(and my msg)"
But I got response "Yes I got that segment"
Any suggestion please...
io.sockets.on('connection', function (socket) {
app.post('/mysegment', ...
What is happening here, is that each time any client connects with websockets, a new handler is added to all /mysgment POST request. Then, when anybody send a POST to /mysegment, all connected clients will get userData... which is probably not what you want.
To keep it simple, stick to using sockets for one thing, and normal HTTP for others.
Otherwise you'll have to share the session and/or find the corresponding socket.
You can access the socket object in your express routes like this (in scoket.io v4):
var socket = io.sockets.on('connection', function (socket) {
socket.on('getUser',function(msg){
console.log("Yes Socket work Properly "+msg);
});
});
app.post('/mysegment',function(req,res){
var userData = req.body;
socket.emit('sendUser', userData);
res.send("yes I got that segment");
});