I have create a socket in app.js
APP.JS
var app = express();
var server = require('http').createServer(app)
var io = require('socket.io').listen(server);
app.set('socketio', io);
io.sockets.on('connection', function(socket){
console.log('Connesso');
socket.on('message', function(data){
console.log("Oo");
})
})
In my html page I have a js script
newex.onsubmit = function(event){
event.preventDefault();
socket.emit('message', {
name: document.getElementById('name').value,
desc: document.getElementById('description').value
});
}
So, when an user submit a form, the socket should send a "signal", but I want catch the signal in a routing page, not in my app.js
I tried with:
ROUTING PAGE
io = req.app.get('socketio');
io.on('message', function(message){
console.log(message);
})
But it doesn't work! I get that I need to put io.on(...) into io.sockets.on clousure but I don't get why. Can you explain me mechanism of socket.io?
EDIT
I set 'socket' in this way and I try code of tbking but it doesn't work anyway
io.sockets.on('connection', function(socket){
console.log('Connesso');
app.set('socket', socket);
//socket.on('message', function(message){console.log("Ricevuto")})
})
You need to listen to the messages from the specific socket the client is connected to.
Try this in your routing file:
var socket = req._socket;
socket.on('message', function(message){
console.log(message);
})
Related
Socket.io closes the connection when user try to close the tab or window but it does not when user navigate to other route in same angular app, the disconnect event will not fire in that case.
server-side:
io.on('connection', function (socket) {
console.log('a user connected');
socket.on('disconnect', function () {
console.log('user disconnected');
});
});
the socket.disconnect() method will not work.
I am trying to use CanDisconnect routing guards but does not know how to use that to close the connection.
server side:
// dependencies
var app = require('express')();
var http = require('http').createServer(app);
var io = require('socket.io')(http);
//importing routes
var loginRouter = require('./routes/loginRoutes');
var chatRouter = require('./routes/chatRoutes');
app.use('/', loginRouter); // applying routes to the app
app.use('/', chatRouter); // applying routes to the app
// starting the server
http.listen(3000, function(){
console.log('server is listening on port '+PORT);
});
// socket.io ===================================
io_public = io.of('/public'); // namespace public
io_public.on('connection', function(socket){
socket.on('adduser', function(username){
socket.username = username;
socket.room = 'public'; //assign default public room
socket.join(socket.room);
socket.emit('server', 'you have connected to a public room');
socket.broadcast.to('public').emit('server',socket.username + ' has connected to this room');
});
socket.on('disconnect', function(){
socket.broadcast.to('public').emit('server',socket.username + ' has left the room');
socket.leave(socket.room);
});
});
client side:
var socket = io('http://localhost:3000/public');
var user = Cookies.get('user');
socket.on('connect', function(){
socket.emit('adduser', user);
});
socket.on('server',function(msg){
$('#conversation').append('<li> <b>Server: </b>'+msg+'</li>');
});
I am loading this client script in home component on dashboard/home, when user moves to dashboard/contacts it does not disconnect. It also create duplicate socket listeners also because this client script will reloaded every time the component is loaded.
starting state
move to contact routes:
Reloading home component
You can generate an Angular service for connecting and disconnecting. Call the service to Connect on the ngOnInit on the components you want and then call the disconnect method on the ngOnDestroy method.
You can also try to do the same implementing Guards like you said.
Inside component.ts
ngOnInit() {
this.chatService.connect()
}
ngOnDestroy(){
this.chatService.disconnectSocket();
}
Inside ChatService
import { io, Socket } from "socket.io-client";
private socket: Socket;
constructor() {
this.socket = io("http://localhost:4000");
}
connect(){
this.socket.connect()
}
disconnectSocket(){
this.socket.disconnect()
}
When the client connects to the server a message is supposed to be emitted to the console. I'm not getting any errors so I'm confused as to what my problem actually is.
Server: As you can see the client connects.
Client: The message doesn't appear in the console.
(Forgive me for the links, I don't have 10 reputation)
How do I get the message to print to the console?
I've read other posts like this one, but they weren't helpful :(
When you do io.connect(), that call is asynchronous and not immediate. You cannot immediately emit to the server until the client generates the connect event:
var socket = io.connect()
socket.on('connect', function() {
// it is safe to call `.emit()` here
socket.emit("sndMsg", someData);
});
index.html
<html>
<head>
<script src='/socket.io/socket.io.js'></script>
<script>
var socket = io();
socket.on('welcome', function(data) {
addMessage(data.message);
// Respond with a message including this clients' id sent from the server
socket.emit('i am client', {data: 'foo!', id: data.id});
});
socket.on('time', function(data) {
addMessage(data.time);
});
socket.on('error', console.error.bind(console));
socket.on('message', console.log.bind(console));
function addMessage(message) {
var text = document.createTextNode(message),
el = document.createElement('li'),
messages = document.getElementById('messages');
el.appendChild(text);
messages.appendChild(el);
}
</script>
</head>
<body>
<ul id='messages'></ul>
</body>
</html>
server.js
var http = require('http'),
fs = require('fs'),
// NEVER use a Sync function except at start-up!
index = fs.readFileSync(__dirname + '/index.html');
// Send index.html to all requests
var app = http.createServer(function(req, res) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.end(index);
});
// Socket.io server listens to our app
var io = require('socket.io').listen(app);
// Send current time to all connected clients
function sendTime() {
io.emit('time', { time: new Date().toJSON() });
}
// Send current time every 10 secs
setInterval(sendTime, 10000);
// Emit welcome message on connection
io.on('connection', function(socket) {
// Use socket to communicate with this particular client only, sending it it's own id
socket.emit('welcome', { message: 'Welcome!', id: socket.id });
socket.on('i am client', console.log);
});
app.listen(3000);
Hi i am working with socket.io and node.js (express.js).
I saw a lot of examples, coding from the app.js file. Now i would like to organize better the code, i would like to have all my sockets.io handlers in other modules/files.
This is what i have now:
app.js
var moduleExports = require('./routes/moduleExports');
app.get('/', function(req, res){
res.sendfile(path.join(__dirname + '/index.html'));
io.on('connection', function(socket){
moduleExports.socketio(io, socket);
});
});
moduleExports.js
module.exports = {
init: function(){
//some other functions
}, socketio: function(io, socket){
socket.emit('chat', 'Wellcome!');
socket.on('chat', function (data) {
socket.broadcast.emit('chat', data);
//socket.broadcast.emit('chat', data);
});
socket.on('disconnect', function () {
socket.broadcast.emit('chat', 'Disconnected');
//socket.broadcast.emit('chat', data);
});
}
};
PROBLEM:
If I open 2 different browsers, one browser is for John and one browser is for Doe.
If John sends a message, Doe recieve it two times. If I open again a third browser, and send a message from John, Doe and the third browser are reciving three times the message.
I dont know exactly why this happen. I know something is happen with the "moduleExports.js" file. But I need a way to code my socket.io handlers outside of app.js. So i thought this would be a good pattern but it isnt.
By the way, the client code (it works):
<script src="/socket.io/socket.io.js"></script>
var socket = io();
function submit(){
socket.emit('chat', $('#m').val());
$('#m').val('');
return false;
}
The io.on('connection' you should have it just once in your code, everytime a client connects to your server that event will be thrown, if you have it multiple times I guess it runs more times. What I would do is the the following:
var moduleExports = require('./routes/moduleExports');
io.on('connection', function(socket){
moduleExports.socketio(io, socket);
});
app.get('/', function(req, res){
res.sendfile(path.join(__dirname + '/index.html'));
});
Should I put the redis subscription event out of the io.connect callback if I want to send the data to everyone who is connected? Or is it better to put it inside the io.connect like this:
io.on('connection', function(socket){
sub.on('message',function(channel,msg){
Project.findAll({ where: {id: msg} },{raw:true}).success(function(d) {
console.log(d);
io.sockets.emit("activities",d);
})
});
});
Would there be any difference?
Node.js
var express = require('express'),
app = express(),
http = require('http').createServer(app),
io = require("socket.io").listen(http),
redis = require("redis"),
Sequelize = require('sequelize');
var pub = redis.createClient();
var sub = redis.createClient();
sub.subscribe('global');
app.get('/p/:tagId', function(req, res){
res.render('index.html')
});
sub.on('message',function(channel,msg){
Project.findAll({ where: {id: msg} },{raw:true}).success(function(d) {
console.log(d);
io.emit("activities",d);
})
});
io.on('connection', function(socket){
//** code **//
})
Can anyone show me what's wrong with the node.js's code?
Your second code sample looks correct. You don't want to put the sub.on('message', function(channel, msg) { inside the socket.io connection handler. That would add a new event handler every time someone connects.
Did you test if it is working? You need to publish something onto the channel global for the message callback to be triggered.
pub.publish('global', 'here is a message');
I have an express node.js server serving Socket.io. I would like the ability to make get requests to the express server that will automatically send a message to a channel.
var app = require('express').createServer()
, io = require('socket.io').listen(app)
app.listen(80);
app.get('/:channel/:message', function (req, res) {
//Code to create socket
socket.emit("sent from get", {channel:req.params.channel, message:req.params.message})
});
io.sockets.on('connection', function (socket) {
socket.on('sent from get', function (data) {
socket.broadcast.to(data.channel).emit('channel message', { message: data.message});
});
});
How to I create (and destroy) a socket connection in the app.get block?
(For clarity, I want to use this to send a quick message from a rails server when a particular object is saved, and have a message pushed to each appropriate user.)
io.sockets.in(req.params.channel).emit("channel message", {mes:req.params.message})
That will send a message to all users in the requested channel.
var chat = io.of('/chat').on('connection', function (socket) {
socket.emit('a message', { that: 'only', '/chat': 'will get' });
chat.emit('a message', { everyone: 'in', '/chat': 'will get' }); });
The following example defines a socket that listens on '/chat'