How to know when channel is subscribed/unsubscribed with socket.io - javascript

Just searched all the web to find how can I track inside node.js server when a channel is subscribed or unsubscribed. What I can do right know is the connect and disconnect bindings, but no clue how to do it with channels.
io.sockets.on('connection', function (socket) {
console.log("["+socket.id+"] Connected");
// handler to know when a socket subscribed a channel (*) ?
// handler to know when a socket unsubscribed a channel (*) ?
socket.on('disconnect', function () {
console.log("["+socket.id+"] Disconnect");
});
});
Is it possible?

You are looking for "socket.of('channelName')" ...
See Socket.io docs
SERVER:
var io = require('socket.io').listen(80);
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'
});
});
var news = io
.of('/news')
.on('connection', function (socket) {
socket.emit('item', { news: 'item' });
});
CLIENT:
<script>
var chat = io.connect('http://localhost/chat')
, news = io.connect('http://localhost/news');
chat.on('connect', function () {
chat.emit('hi!');
});
news.on('news', function () {
news.emit('woot');
});
</script>

Related

Socket.io call ack on connect event

Is there any way too utilize the ack argument on the connect event in Node.js? Something like this:
//client.js
socket.on('connect', (data) => {
console.log(data); // I want to print 'lol' here
});
//server.js
io.on('connect', (socket, ack) => {
ack('lol'); // TypeError: ack is not a function
});
Reference for ack: https://socket.io/docs/server-api/#socket-emit-eventname-args-ack
It doesn't look like the socket.connect() or socket.open() methods take an ack argument. I generally will emit a 'connected' event from the server once a connection from the client is established. You can receive this emission and add your behavior as needed.
server.js
io.on('connect', function(socket) {
socket.emit('connected');
});
client.js
socket.on('connected', function() {
console.log('Connected');
});
There is no specific ack data that you can send for the connect event. You can just .emit() a message to the client when the server receives the connect.
//client.js
socket.on('connect', () => {
console.log('client connected');
});
socket.on('welcome', function(data) {
console.log(data); // 'lol'
});
//server.js
io.on('connect', (socket) => {
// send welcome message upon connect
socket.emit('welcome', 'lol');
});

Client can receive events but can't emit

I have my client set up like this:
var socket = io();
socket.on('thing', function(socket){
console.log('A user connected: ' + socket.data);
});
function sendThing(){
var data = document.getElementById('myInput').value;
console.log(data)
socket.emit('message', { message: data });
}
I can receive events just fine, I have my server emit an event and it logs out fine:
io.on('connection', (socket) => {
io.emit('thing', { data: 'thisisathing' });
});
Edit: my on.message function:
io.on('message', (socket) => {
console.log(socket.message);
});
But my server never receives a message because the emit on the client side does not fire. Socket exists and I get no errors.
How do I fix this?
Try nesting your listener within your connection function like:
io.on('connection', (socket) => {
socket.on('message', (socket) => {
console.log(socket.message);
});
});
as described in the docs
I think you have to listen to message inside the connection :
io.on('connection', (socket) => {
socket.emit('thing', { data: 'thisisathing' });
socket.on('message', (data) => {
console.log(data.message);
});
});

ember-cli-mirage redirects socket.io client, which is injected in mirage

the issue that occurs here, is that, when i connect between sample socekt.io client with this socket.io server by node.js ( just running two terminals and opening socket connection between client and server)
I have no problems. But, when I am trying to inject this socket.io-client into my Ember.js application, precisely to ember-cli-mirage it redirects my client from given address : ( 'http: //localhost:8080') to something like http: //localhost:8080/socket.io/?EIO=3&transport=polling&.....
also Mirage displays me an error that I cannot handle, even by setting up precise namespace, routing the wsClient.connect() method or calling this.passthrough() , before calling wsClient.connect() .
I also paste the the screenshot of error from inspect console in browser:
error image
Do you have any idea how to resolve this problem? Thank you in advance and I also hope that the topic is not duplicated.
// server.js
var app = require('http').createServer(handler);
var io = require('socket.io')(app);
app.listen(8080);
function handler(req, res) {
res.writeHead(200);
res.end('default.index');
}
var rooms = {
'room1': [
],
'room2': [
]
};
io.on('connection', function(socket) {
console.log('client connected');
socket.on('join', function(roomName) {
rooms[roomName].push(socket.id);
socket.join(roomName);
});
socket.on('leave', function(roomName) {
var toRemove = rooms[roomName].indexOf(socket.id);
rooms[roomName].splice(toRemove, 1);
socket.leave('roomName');
});
socket.on('eNotification', function(data) {
console.log(data);
io.to(socket.id).emit('eNotificationCall', data);
io.to('room2').emit('eventNotification', data);
});
socket.on('gNotification', function(data) {
console.log(data);
io.to(socket.id).emit('gNotificationCall', data);
io.to('room1').emit('diagram1Notification', data);
});
socket.on('close', function() {
console.log('client disconnected');
});
});
//client.js
var wsClient = {
socket: null,
connect: function() {
this.socket = io.connect('http://localhost:8080');
this.socket.on('connect', function() {
console.log('mirage client connected!');
});
},
send: function(eventData, graphData) {
this.socket.emit('eNotification', eventData);
this.socket.emit('gNotification', graphData);
}
};
export default wsClient;
//config.js
import wsClient from './websockets/client';
export default function() {
wsClient.connect();
console.log(wsClient.socket);
var graphData = {X: "2", Y: "3"};
var eventData = {myDAta: 'myDAta', message: 'message'};
setInterval(function() {
wsClient.send(graphData, eventData);
}, 5000);
}
If you call this.passthrough() with no args it only allows requests on the current domain to passthrough. It looks like the websocket connection is on a different port, so try specifying it directly:
this.passthrough('http://localhost:8080/**');
See the docs for more information.

What Express websocket events exist?

I am wondering what websocket events exist So far I have only been using the ws.on('message') event, but I would like to use an event that is triggered when the connection is established and closed. I tried adding ws.on('connection'), but that didn't get triggered.
My code:
app.ws('/', function (ws, req) {
ws.on('message', function (textChunk) {
//do stuff
}
});
});
Do I need some client side programming to do this?
I tried adding this, but it didn't trigger when I connected from my client.
ws.on('request', function () {
console.log("request");
});
The function provided to app.ws is the one executed when a new websocket is opened. So use it this way:
app.ws('/', function (ws, req) {
console.log("New connection has opened!");
ws.on('close', function() {
console.log('The connection was closed!');
});
ws.on('message', function (message) {
console.log('Message received: '+message);
});
});
After looking at the source code for express-ws it looks like you can do the following.
var express = require('express');
var app = express();
var expressWs = require('express-ws')(app);
// get the WebsocketServer instance with getWss()
// https://github.com/HenningM/express-ws/blob/5b5cf93bb378a0e6dbe6ab33313bb442b0c25868/index.js#L72-L74
expressWs.getWss().on('connection', function(ws) {
console.log('connection open');
});
// ... express middleware
// ... websocket middle ware
app.ws('/', function(ws, req) {
ws.on('message', function(msg) {
console.log(msg);
});
});
app.listen(3000);
Old Response
There are the following:
close
error
message
open
https://developer.mozilla.org/en-US/docs/Web/API/WebSocket#Attributes
Okay I found one more event that actually triggers. Now if only I would find one that gets called once on open connection.
app.ws('/', function (ws, req) {
ws.on('close', function() {
console.log('close connection');
});
ws.on('message', function (textChunk) {
//do stuff
}
});
});

Connections are duplicationg in Socket.io

I'm developing a chat app, and the connections are duplicating.
In my route, I have:
exports.index = function (io) {
return function (req, res) {
var userId;
res.render('index', {
title: 'RandomChat.me',
test: 'test2'
});
io.sockets.on('connection', function (socket) {
userId = socket.id;
console.log("+++++++++++++++++++" + userId);
socket.emit('addUser', { userId: userId });
socket.room = 'General';
socket.join(socket.room);
socket.on('sendMessage', function (data) {
console.log(data.room);
// socket.broadcast.emit('receiveMessage', { data: data });
socket.broadcast.to(data.room).emit('receiveMessage', { message: data.message });
});
});
}
};
Client-side something like:
var socket = io.connect('http://domain.com:3000');
var userId;
socket.on('addUser', function(data) {
userId = data.userId;
console.log(userId);
});
socket.on('receiveMessage', function (data) {
console.log(data);
});
var room: "General";
var message: "Test";
socket.emit('sendMessage', { room : room, message: message });
console.log(userId + " " + message)
If I go to the app and check the console log, I see the userId, and when I reload the page, I see the same ID's twice, if I reload again, I see it 3 times and so on.
The same thing is happening in the node.js console.
So basically when connections/users are duplicated, the other users receive duplicate messages, as the sendMessage/receiveMessages functions are run more than once.
Help appreciated.
The problem is this line
io.sockets.on('connection', function (socket) {
You should not put these inside a request handler because its just wrong to add a connection handler for socket for each request. Try doing these outside the request handler and use the io object to emit/broadcast events to sockets from the request handler.
Using io.sockets.once('connection', function (data){}) instead of io.sockets.on('connection', function (data){}) fixed it. It doesn't try to recover a lost connection.

Categories