Socket functions in a separate file in Express server - javascript

I simply want to implement my socket functions in a separate file (i.e not in the express server implementation) like (/routes/sockets.js). How can I do that?
My express server:
var express = require('express')
, routes = require('./routes')
, socket = require('./routes/socket.js')
, http = require('http')
, path = require('path');
,app = express();
var server = http.createServer(app);
var io = require('socket.io').listen(server);
server.listen(app.get('port'), function(){
console.log("Express server listening on port " + app.get('port'));
});
The socket listener (currently in the same file as above server implementation)
sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) { //event on client
console.log('my other event data ' + data);
});
});

Ok I figured it out by my self. You can call the required sources using
io.sockets.on('connection', require('./routes/socket'));

Related

Node js - Socket.io - client is not connecting to socket.io server

I am trying to connect to a socket.io-client using this as my server.js:
var express = require('express');
var app = express();
var server = app.listen(3001);
var io = require('socket.io').listen(server);
app.get('/input', function(req, res){ // This is because in the server the port 3001 is open and I only can use the route 'input' to connect to the node server
res.send('Hello world');
});
io.on('connection', function(socket) {
console.log('Client connected.');
// Disconnect listener
socket.on('disconnect', function() {
console.log('Client disconnected.');
});
});
And in my client file:
var socket = io.connect('https://urlofthepage:3001', {reconnect: true});
socket.on('connect', function() { console.log('connect'); });
// or (I tried with both)
var socket = io.connect('https://urlofthepage:3001/input', {reconnect: true});
socket.on('connect', function() { console.log('connect'); });
But when I go to urlofthepage/input show me
Hello world
but in the node server not show anything like
Client connected.
And in the page where I have the client.js file the console show me
3001/socket.io/?EIO=3&transport=polling&t=MBSSeZj net::ERR_CONNECTION_TIMED_OUT
Edit: It's on an online server, which has a wordpress installed, and my socket.io.js script is urlofpage/socket.io/socket.io.js
AND (I don't know if this matters, it is a test server, and the url has https, but it indicates that it is not secure, we have to change it)

Socket.IO Client How to Connect?

I was following the second example here:
https://github.com/socketio/socket.io-client
and trying to connect to a website that uses websockets, using socket.io-client.js in node.
My code is as follows:
var socket = require('socket.io-client')('ws://ws.website.com/socket.io/?EIO=3&transport=websocket');
socket.on('connect', function() {
console.log("Successfully connected!");
});
Unfortunately, nothing gets logged.
I also tried:
var socket = require('socket.io-client')('http://website.com/');
socket.on('connect', function() {
console.log("Successfully connected!");
});
but nothing.
Please tell me what I'm doing wrong. Thank you!
Although the code posted above should work another way to connect to a socket.io server is to call the connect() method on the client.
Socket.io Client
const io = require('socket.io-client');
const socket = io.connect('http://website.com');
socket.on('connect', () => {
console.log('Successfully connected!');
});
Socket.io Server w/ Express
const express = require('express');
const app = express();
const server = require('http').Server(app);
const io = require('socket.io')(server);
const port = process.env.PORT || 1337;
server.listen(port, () => {
console.log(`Listening on ${port}`);
});
io.on('connection', (socket) => {
// add handlers for socket events
});
Edit
Added Socket.io server code example.

Express nodejs socket.io with cordova

I'm trying to implement socket.io on my server. This server is an API (express nodejs).
The server side is simple, but for the client side I'm using phonegap/cordova.
I don't use a phone to test what I do, I use my browser (chrome).
Si this the server side :
var express = require('express'); // call express
var app = express(); // define our app using express
var http = require('http').Server(app);
var io = require('socket.io')(http);
io.on('connection', function(socket){
console.log('a user connected');
console.log(socket);
socket.on('disconnect', function () {
console.log('socket disconnected');
});
io.emit('text', 'wow. such event. very real time.');
});
for now, this is simple,
But for the client side I am completely confuse (cordova phonegap),
This is what I have :
index.html
<script type="text/javascript" src="http://cdn.socket.io/socket.io-1.0.3.js"></script>
<script>
var socket = io.connect('http://localhost:8080');
socket.on('news', function (data) {
console.log('send')
socket.emit('my other event', { my: 'data' });
});
</script>
Nothing appears but errors like
GET http://localhost:8080/socket.io/?EIO=2&transport=polling&t=1462638049681-3 net::ERR_CONNECTION_REFUSED
and nothing on my server
any ideas to help me ? thanks :)
Your server is not listening on port 8080. That's why when you try to connect from browser to var socket = io.connect('http://localhost:8080');, it shows 'Connection Refused'.
This edit would work for you.
var express = require('express'); // call express
var app = express(); // define our app using express
var http = require('http').Server(app);
var io = require('socket.io')(http);
io.on('connection', function(socket){
console.log('a user connected');
console.log(socket);
socket.on('disconnect', function () {
console.log('socket disconnected');
});
io.emit('text', 'wow. such event. very real time.');
});
//Now server would listen on port 8080 for new connection
http.listen(8080, function(){
console.log('listening on *:8080');
});

How can I emit events to connected sockets using socket.io from within my Express 4 routes?

This is a question other people have asked, but I can't manage to benefit from the answers they've been given, due to the different Express setup I have.
I've got socket.io implemented and working in a simple way on my server. This is how it works:
In bin/www:
#!/usr/bin/env node
var debug = require('debug')('gokibitz');
var app = require('../../server');
app.set('port', process.env.PORT || 3000);
var server = app.listen(app.get('port'), function() {
debug('Express server listening on port ' + server.address().port);
});
var io = require('socket.io').listen(server);
io.on('connection', require('../routes/socket.js'));
All my routes and other Express setup is in ../../server.js.
var routes = require('./server/routes/index');
var user = require('./server/routes/user');
...
app.use('/', routes);
app.use('/api/user/', user);
...
app.use('*', routes);
Then in ../routes/socket.js, I've got this boilerplate:
module.exports = function (socket) {
socket.emit('send:news', { hello: 'world' });
setInterval(function () {
socket.emit('send:time', {
time: (new Date()).toString()
});
}, 1000);
return socket;
};
This is working beautifully, I might add. But now I want to be able to emit events from the various routes in my quite-ordinary Express app, and I can't for the life of me figure out the right way to get a reference to the socket object I need.
Example: when a user makes a comment, I'd like to emit an event to all connected users notifying them of the new comment. From my routes file (./server/routes/user.js), how can I get access to the object I need to emit events?
Here's a skeleton of the relevant bits from a route file:
var express = require('express');
var router = express.Router();
router.post('/', function (req, res) {
...
});
module.exports = router;
The only place I can access it is in the ../routes/socket.js file, which is useless.
All of the routes are set in a app.js before there's any io or socket object to pass in.
Should I be able to require('socket.io') and use it somehow to emit to all connected sockets?
Is there a sensible way to store the connected sockets on ../routes/socket.js so it can be required and emitted to from other routes?
Can anyone steer me in the right direction?
I was able to ultimately get things working using this example:
https://github.com/expressjs/generator/issues/45#issuecomment-53719435
I created a new file called server/io.js:
var io = require('socket.io')();
io.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
module.exports = io;
Then I updated server/bin/www to this:
#!/usr/bin/env node
var debug = require('debug')('gokibitz');
var app = require('../../server');
var io = require('../io');
app.set('port', process.env.PORT || 3000);
var server = app.listen(app.get('port'), function() {
debug('Express server listening on port ' + server.address().port);
});
io.attach(server);
Then, in my route, I use this:
var io = require('../io');
...
io.emit(...);
The missing piece for me, at least, was the ability to create the io object separately, return the correct object, then use io.attach(server) inside bin/www to start it up at the right point.
Hopefully this will help someone else following in my footsteps.
I think you are confused with the concepts. The socket.io lib uses or emulate a websocket (bidirectional socket) with the client, and have not relation with routes.
You can send a notification to all sockets using the io object:
io.emit('message_to_all', true);
You have to an array on io.sockets, with all sockets.
You can uses namespaces or rooms to, I recomend you learn the documentation:
http://socket.io/docs/rooms-and-namespaces/#
Add something:
If you want to send a message to all people in the same route, you can join to a channel with the same name of the path.
For example, in the client:
var socket = io(window.location.href); // Or route..
And the server:
var nsp = io.of('/the/specific/route');
nsp.on('connection', function(socket){
// ...
});
nsp.emit('message_to_all_in_route', data);
About the last question editing:
You can send the io object in request or response object to routes, using the Express midleware API:
For example:
#!/usr/bin/env node
var debug = require('debug')('gokibitz');
var app = require('../../server');
app.set('port', process.env.PORT || 3000);
var server = app.listen(app.get('port'), function() {
debug('Express server listening on port ' + server.address().port);
});
var io = require('socket.io').listen(server);
app.use(function (req, res, next) {
res.io = io;
next();
});
io.on('connection', require('../routes/socket.js'));
And in the route:
route.post('/post/:id/comments', function (req, res) {
// Do your logic
var postio = res.io.of('/post/' + req.params.id);
postio.emit('new_comment', commentData);
});
As I said in my comment, you can send to all connected clients with:
io.emit(msg, data);
This will require access to the io object that you created in your first module. The usual way to share that with your module with your routes modeule would be to export a method from the routes module that lets you pass it the io object and then after you've required in the routes module and created the io object, you can just call that method to pass the io object to the routes module and it can save it locally for future use.
io is just a shared object like the app object is. If you want a module to be able to use a shared object, the usual way is that you call some method in that module to share with it some objects that it can then use.
I have made a new file sockets.js in that file:
var socketio = require('socket.io');
var io;
module.exports = {
socketServer: function (app) {
io = socketio.listen(app);
io.on('connection', function (socket) {
console.log(Object.keys(users));
socket.on('message', function (data) {
io.emit('updateChat', 'Hello World!')
});
});
}
}
And in my app.js:
var express = require('express');
var app = express();
var http = require('http').createServer(app);
var port = process.env.PORT || 3000;
var io = require('./sockets').socketServer(http);
http.listen(port, function () {
console.log('SERVER RUNNING.. PORT: ' + port)
});
This is working for me. Good Luck!

Socket.io: io.connect doesn't work

I use node.js with express.js framework. I Tried connect to server using io.connect on client side.
Template:
html
head
title Example chat
script(src="http://code.jquery.com/jquery-latest.min.js")
script(src="http://cdn.socket.io/stable/socket.io.js")
script(src="javascripts/chat.js")
body
form
input(type="text" name="msg")
input(type="submit")
It's chat.js:
var socket = io.connect('//localhost:8080');
app.js socket.io require:
var io = require('socket.io').listen(8080);
Firebug gives an error:
TypeError: io.connect is not a function
What is it? How to fix it?
Thanks you.
Server-side
var express = require('express');
var http = require('http');
var io = require('socket.io');
var app = express()
, server = require('http').createServer(app)
, io = io.listen(server);
server.listen(app.get('port'), function(){
console.log("✔ Express server listening on port %d in %s mode", app.get('port'), app.settings.env);
});
io.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
Client-side
<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>
Then if you're wondering where that socket.io.js is found, it's automatically generated.

Categories