You suppose i have 3 room such as room1, room2 and room3
i want to join some users to this rooms, how can i do that?
my code doesn't correct and i can't do that
var socket = require('socket.io'),
express = require('express'),
fs = require('fs'),
app = express(),
server = require('http').createServer(app),
io = socket.listen(server),
port = process.env.PORT || 3000,
redis = require("redis"),
redisClient = redis.createClient(),
forever = require('forever'),
log = require('log4node');
var io_redis = require('socket.io-redis');
io.adapter(io_redis({host: 'localhost', port: 6379}));
require('sticky-socket-cluster/replace-console')();
var options = {
workers : require('os').cpus().length,
first_port : 8000,
proxy_port : 3000,
session_hash: function (req, res) {
return req.connection.remoteAddress;
},
no_sockets: false
};
var room = ["room1","room2","room3"];
require('sticky-socket-cluster')(options, start);
function start(port) {
io.sockets.on('connection', function (socket) {
socket.on('room1', function (room) {
socket.join(room[0])
});
socket.on('room2', function (room) {
socket.join(room[1])
});
});
server.listen(port, function () {
console.log('Express and socket.io listening on port ' + port);
});
}
when i use this code to join users as :
socket.on('room1', function (room) {
socket.join(room[0])
});
i get no result and code doesn't work and i don't know how can i do that
Related
I am currently doing socket.io project. When I connect to new socket it shows my input username on the "usersDiv" where all clients should be there. But the thing is when I open another tab and input my name, it only has the name of the new client but when I switch to the other tab 2 client names are there. the new client doesn't show recent connected client input.
Here is my Code:
app.js(server)
const app = express();
const socket = require('socket.io');
const server = app.listen(8001, function(){
console.log('listening to port 8001')
});
const io = socket(server);
app.use(express.static('./views'));
app.set('views','./views');
app.set('view engine','ejs');
app.get('/', function(req, res){
res.render('index');
});
io.on('connection', function(socket){
console.log('Made Connection');
socket.on('username', function(data){
let users = [];
users.push(data.userName);
io.emit('joined', users)
});
});
client.js(client)
let username = prompt('What is your username?');
let usersDiv = document.getElementById('users');
let container = document.getElementById('container');
let socket = io();
let clear = document.getElementById('clear');
let circle = document.createElement('div');
socket.emit('username', {
userName: username
})
socket.on('joined', function(data){
usersDiv.innerHTML += data + '<br>';
})
As Chris G pointed out you need to declare let users = []; outside of the event handler connection.
For an example in app.js using sockets with a express server:
const express = require('express');
const app = require('express')();
const server = require('http').createServer(app);
const io = require('socket.io')(server);
app.use(express.static("public"));
app.set('view engine','ejs');
app.get('/', function(req, res){
res.render('index');
});
let users = [];
io.on('connection', function(socket) {
console.log('Made Connection');
socket.on('username', function(data) {
io.emit('joined', users);
users.push(data.userName);
});
});
const listener = server.listen(process.env.PORT, () => {
console.log('app is running on port ' + listener.address().port);
});
Then for client side you can create path like: public/client.js
let username = prompt('What is your username?');
let usersDiv = document.getElementById('users');
let container = document.getElementById('container');
let clear = document.getElementById('clear');
let circle = document.createElement('div');
let socket = io.connect();
socket.emit('username', {
userName: username
});
socket.on('joined', function(data) {
usersDiv.innerHTML = data.join('<br>');
});
Also you need to be careful using html when you are appending the username or messages someone could do a xss attack.
I am building a real-time notification system using socket.io. This is my server-side code at the moment:
bin/www:
var app = require('../app');
var server = http.createServer(app);
var io = app.io
io.attach(server);
server.listen(port, function(err) {
if (err) console.log(err);
console.log('Listening on port ' + port + '...');
});
app.js:
var socket_io = require('socket.io');
var express = require('express');
var app = express();
var io = socket_io();
app.io = io;
require('./config/socket')(app.io);
config/socket.js:
var User = require('../controllers/user');
module.exports = function (io) {
io.on('connection', function (socket) {
console.log('Socket.io connected');
socket.emit('connection', "Connection created.");
socket.on('send notification', function(data) {
User.createNotification(socket.request.user, data);
});
});
};
routes/index.js:
var express = require('express');
var User = require('../controllers/user');
var router = express.Router();
router.post('/order', User.order);
module.exports = router;
controllers/user.js:
var User = require('../models/user').model;
var io = require('socket.io');
module.exports = {
order: function(req, res) {
/* some create order code */
io.emit('send notification', 'Your order was successful!');
res.sendStatus(200);
}
}
I keep getting the error TypeError: io.emit is not a function whenever I try to call the route POST /send even though I am clearly initiating socket.io in my app.js and bin/www files and requiring it in controllers/user.js. All the examples I've seen online emit notifications from within this part:
io.on('connection', function (socket) {
socket.emit(event, msg);
});
but I want my notifications to be triggered from the middleware so I can send custom notifications to the user when certain events happen in the application backend.
Try the following instead:
io.on('connection', function(socket){
socket.on('xxx', function(obj){
io.emit('xxx', {xxx: xxx})
})
})
This should suppress your TypeError:.
I'm trying to implementing cluster on nodejs and using Socket.io in my application, after some search and introduced about that and finding sticky-socket-cluster i try to use that, here is sample code which i use the documentetion of library, but login socket not working and dont print log
require('sticky-socket-cluster/replace-console')();
var options = {
workers : require('os').cpus().length, // total workers (default: cpu cores count).
first_port : 8000, // 8000, 8001 are worker's ports (default: 8000).
proxy_port : 3000, // default (5000).
session_hash: function (req, res) {
return req.connection.remoteAddress;
},
no_sockets: false // allow socket.io proxy (default: false).
};
require('sticky-socket-cluster')(options, start);
function start(port) {
var express = require('express');
var http = require('http');
var app = express();
var server = http.Server(app);
var socket = require('socket.io')(server);
socket.on('connection', function (socket) {
console.log("socket.io connection handler...");
});
socket.on('login', function (data) {
console.log(data.username);
});
server.listen(port, function () {
console.log('Express and socket.io listening on port ' + port);
});
}
I have this index.js file on the client:
var socket;
var init = function() {
// Setup Socket:
socket = io.connect();
// Setup Event Handlers:
setEventHandlers();
// Connect to Server:
socket.emit('connect', {
name : "User Name"
});
console.log("Client Init Complete.");
}
var setEventHandlers = function() {
// Set Routes For Connections
socket.on("connection resp", onConnected);
}
var onConnected = function(data) {
console.log(data.resp);
}
And I have this code on the server:
// SETUP:
var express = require('express');
var app = express();
var http = require('http').Server(app);
var request = require('request');
var path = require('path');
var socket = require('socket.io')(http);
var server_port = process.env.OPENSHIFT_NODEJS_PORT || 8080;
var server_ip_address = process.env.OPENSHIFT_NODEJS_IP || '0.0.0.0';
var bodyParser = require('body-parser')
var fs = require('fs');
// SETUP:
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended : false
}));
app.configure(function() {
app.use(express.static(path.join(__dirname, 'public')));
})
var setEventHandlers = function() {
socket.sockets.on("connection", onInit);
};
var onInit = function(client) {
client.on("connect", onConnect);
};
var onConnect = function(data) {
console.log("Called");
}
// Send index page html
app.get('/', function(req, res) {
res.sendfile("public/html/index.html");
});
// Turn on server
http.listen(server_port, server_ip_address, function() {
console.log("App Listening on " + server_ip_address + ", server_port "
+ server_port);
});
setEventHandlers();
The issue is that on the onConnect on the server is never called. Eventhough I call socket.emit("connect") on the client.
After further testing, it seems that the socket id is undefined: this.id returns undefined.
You need to add quotes to the parameters in the socket.emit function like this:
// Connect to Server:
socket.emit('connect', {
'name' : 'User Name'
});
You should initialize your socket variable through io.connect("server address") and has i see in your code you have not passed any parameter to io.connect
.If server is in your local machine then connect to it by io.connect("http://localhost").
For more information see Docs. socket.io-client
For example my idea is:
File1.js
io.sockets.on('connection', function (socket) {
socket.on('file1Event', function () {
//logic
});
});
File2.js
io.sockets.on('connection', function (socket) {
socket.on('file2Event', function () {
//logic
});
});
This code is for a node server, will I have problems with this code?
Nope, just use the same "io" object.
File1.js
exports = module.exports = function(io){
io.sockets.on('connection', function (socket) {
socket.on('file1Event', function () {
console.log('file1Event triggered');
});
});
}
File2.js
exports = module.exports = function(io){
io.sockets.on('connection', function (socket) {
socket.on('file2Event', function () {
console.log('file2Event triggered');
});
});
}
app.js
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, fs = require('fs')
, file1 = require('./File1')(io)
, file2 = require('./File2')(io)
app.listen(3000);
function handler (req, res) {
fs.readFile(__dirname + '/index.html',
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
index.html
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost');
socket.emit('file1Event'); // 'file1Event triggered' will be shown
socket.emit('file2Event'); // 'file2Event triggered' will be shown
</script>
Be careful not to generate a new connection event for each file. You should use the same on('connection') event, otherwise after 10 files imported, you will get this error from node: MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 connection listeners added. Use emitter.setMaxListeners() to increase limit.
The better way is to do like this in your main file:
io.on('connection', function (socket) {
require('pathToSocketRoutesFile1')(socket);
require('pathToSocketRoutesFile2')(socket);
require('pathToSocketRoutesFileN')(socket);
return io;
};
and in each separate file:
module.exports = function(socket) {
socket.on('eventName1', function() {
//...
});
socket.on('eventName2', function() {
//...
});
};
Another option is to create a rootSocket which handles the initial connection and then passes the socket to other handlers.
const rootSocket = (io) => {
io.sockets.on('connection', (socket) => {
authorization(socket);
chat(socket);
});
};
exports.default = rootSocket;
You Can use IO module in any route just create global middleware.
socketiomw.js
module.exports = (io)=>{
return (req,res,next)=>{
req.io = io;
next();
}
}
middlewares.js
module.exports.global = {
socketIo:require('./socketiomw'),
// add other global middleware
};
index.js
const express = require('express');
const app = express();
const port = 3000;
const http = require('http');
const server = http.createServer(app);
const { Server } = require("socket.io");
const io = new Server(server);
//global middleware initialization
app.use(require('./middlewares').global.socketIo(io));
app.get('/notify',(req,res)=>{
req.io.emit("hello");
req.io.to("someRoom").emit("some event");
req.io.to("room1").to("room2").to("room3").emit("some event");
req.io.of("/").adapter.on("create-room", (room) => {
console.log(`room ${room} was created`);
});
req.io.of("/").adapter.on("join-room", (room, id) => {
console.log(`socket ${id} has joined room ${room}`);
});
req.json({ success:true })
);
server.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
I used this in global middleware so i can use this io module in any routes
rootSocket.js :
const rootSocket = (io) => {
io.on('connection', (socket) => {
console.log('New connection');
// possibility to outsource events
socket.on('myEvent', () => {
console.log('myEvent triggered');
});
});
}
module.exports = rootSocket;
index.js :
const express = require('express');
const app = express();
//app.use(express.json());
//const cors = require('cors');
//app.use(cors());
const http = require('http');
const server = http.createServer(app);
const socketIo = require('socket.io');
const io = socketIo(server);
const rootSocket = require('./rootSocket')(io);
const port = 8000;
// process.env.PORT for production
server.listen(port, () => console.log('server started on ' + port));