How to change URL Websocket NodeJs (server/client) - javascript

I have a server node Js with express I want to use two socket with my clients in the same page server.js (contains all my controllers), suddenly I want to put the first socket under the url ("/connection"), and A second one under the url ("/giveUserConnected") that will serve me to recupir the connected users, par exemple :
client.html :
var socket = io.connect('http://127.0.0.1:9999/connection');
To contact server.js :
app.get('/connection',function (req,res) {
io.on('connection', function(socket){
console.log('a user connected');
});
});
and another socket2 in client.html :
var socket2 = io.connect('http://127.0.0.1:9999/giveUserConnected');
to contact server.js :
app.get('/giveUserConnected',function (req,res) {
io.on('connection', function(socket){
// to recuper list of users connected
});
});
but it does not work
what is the solution , thank's

You are mixing HTTP requests with socket.io requests, which are two different things.
When you provide a path name to io.connect() (in this case, /connection and /giveUserConnected), the socket.io server uses the path as the name to a namespace that the client connects to.
What I think you want is to just create an event handler for a particular message that will return the list of users. You could use acknowledgement functions for that:
// server
io.on('connection', function(socket) {
socket.on('giveUserConnected', function(fn) {
fn(listOfUsers);
});
});
// client
socket.emit('giveUserConnected', function(users) {
...
});
What listOfUsers is depends on your app.

Related

Broadcast an HTML page to clients in Nodejs with Express

I am developing a client-server app with Nodejs and Express. I'd like to send an HTML page (for example index.html) to all the clients connected to the server.
The server allows the user to log in with name and password, this connection data are stored with an array just like this:
app.post('/myaction', function(req, res) {
clients.push({
"name": req.body.nombre,
"direction":req.connection.remoteAddress,
"time": getDate(),
"role" : role
});
}
So the IP directions are stored in this array too. I can loop with a forEach loop:
clients.forEach(function (client) {
});
Which Express function allows me to send an HTML document to all these clients stored in the array?
You can't achieve that using express. The best approach is to use websockets to push data to all connected clients. I recommend using Socket.io for that since it's really simple to use.
const app = require('express')();
const server = require('http').Server(app);
const io = require('socket.io')(server);
io.on('connection', socket => {
console.log('User connected');
});
app.post('/myaction', (req, res) => {
io.emit('data', 'some-data');
res.send('Data sent to all connected users');
});
client side
// Add socket.io client side library
var socket = io();
socket.on('data', function(data) {
// Do something with the data sent from the server
});

JS Socket | Add full array on the site

So I have a kinda bug on my socket system. I have a array which will be emited if new connection is made to the site, but the problem is that it will be called on all users. So if I have there console.log('new user') then everyone will receive it to the console. My question is, how can I do it so the only one user who just connected receives only it?
Here is my server
io.on('connection', function(client){
clients.push(client.id);
io.emit('add games', coinflips); //This is the line
console.log(clients);
client.on('disconnect', function(){
clients.splice(client.indexOf, 1);
console.log(clients);
});
});
Here is how it's being handled
socket.on('add games', function(data){
if(data.length > 0){
addGames(data);
}
});
you can use the the socket id, socket.id then send to that id.
something along this line.
io.of('/mynamespace').sockets[socketID].emit(...)
Event this logic could work
clients = [];
then whenever a connection is made.
clients.push(socket);
then in the clients array, just index it.
clients[0].emit(...)
this is how you get a id upon connection.
console.info('Client id (id=' + socket.id + ').');
Socket.IO allows you to “namespace” your sockets, which essentially means assigning different endpoints or paths.
Namespaces are useful features to minimize the number of resources (TCP connections) and at the same time separate concerns within your application by introducing separation between communication channels. Multiple namespaces actually share the same WebSockets connection thus saving us socket ports on the server.
Namespaces are created on the server side. But they are joined by clients by sending a request to the server.
---------------------------------------------------------------
Default Namespaces
The root namespace '/' is the default namespace which is joined by clients if a namespace is not specified by the client while connecting to the server. All connections to the server using the socket object client side are made to the default namespace.
--------------------------------------------------------
Custom Namespaces
We can create our own custom namespaces. To set up a custom namespace, we can call the of function on the server-side:
---------------------------------------------------------
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function(req, res){
res.sendfile('index.html');
});
var nsp = io.of('/my-namespace');
nsp.on('connection', function(socket){
console.log('someone connected');
nsp.emit('hi', 'Hello everyone!');
});
http.listen(3000, function(){
console.log('listening on localhost:3000');
});

socket.io authentification not working on first connection

I have a NodeWebkit client which connects to a nodejs server using the socket.io library (JavaScript).
The client launches the connect procedure on the application start but the server does not acknoledge any connections... Though the client's socket has the connected attribute to "true".
You should know that I am using socketio-jwt to authentificate the connection.
Github: https://github.com/auth0/socketio-jwt
I know that the connection does work in a way because if I add :
io.sockets.on('connection', function(){console.log("hello");})
It prints hello !
So it seems that event though the connection is somehow made it doesn't want to do the auth part with the library, resulting in... Well... Nothing.
But that's not all !!
Because if I reboot the app (not the server) then the auth works most of the time ! It acts like a race condition... But I dont see how it could possibly be one... Every line of code is geting executed appart of the success callback of authentification.
I tried connecting to a remote server and on my localhost.
I also tried with an other library of socket auth but I've got the same probleme.
This is the server code:
var session = require('express-session');
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var socketioJwt = require('socketio-jwt');
io.sockets.on('connection', socketioJwt.authorize({
secret: 'some secret',
timeout: 15000 // 15 seconds to send the authentication message
})).on('authenticated', function (socket) {
console.log('[Info]: A user connected to socket = ', socket.decoded_token);
});
});
http.listen(5000, function () {
console.log('listening on *:5000');
});
And now the client code:
this.socket = io.connect('http://' + that.hostName +':' + that.port);
var token = jwt.sign({email: "someEail", pwd: "somePwd"}, fromServerSecret);
this.socket.on('connect', function () {
that.socket.emit('authenticate', {token: token}) //send the jwt
.on('authenticated', function () {
console.log("[Info]: Socket login successfull");
})
.on('unauthorized', function (msg) {
console.log("[Warning]: Socket unauthorized: " + JSON.stringify(msg.data));
throw new Error(msg.data.type);
});
});
The server side log "A user connected to socket" is never shown.
If you have an idear ! Thanks for your time.
Why is there a 'that' on socket.emit (client)? I think you should handle it within the same instance of socket.io - using same 'this' as above

How to send commands from client to server with Socket.io

I would like to send commands from client to server example change image url or label text. I have managed to get the connection working between server & client and the button clicks to work, but i cant manipulate the DOM from the index.js file. Is there a solid way to do this? My client side uses PHP to get data from mySQL database and i'd like to pass that data as array to server and render to view. Here is my code so far:
server: index.js -
var express = require('express');
var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get("/",function(req,res){
res.sendFile(__dirname + '/index.html');
app.use(express.static(__dirname));
});
//This is auto initiated event when Client connects to Your Machien.
io.on('connection', function(client) {
console.log('Client connected...');
client.on('test',function(msg){
console.log("i can see this in cmd console");
// i would like to do like this but it says "document is not defined"
//document.getElementById("mediaContainer").innerHTML = "Paragraph changed!";
});
});
http.listen(3000,function(){
console.log("Listening on 3000");
});
client: app.js -
$(document).ready(function () {
$("#button1").click(function(){
socket.emit('test',$("#someinput").val());
});
});
I would like it to work like this rather:
server: app.js -
$(document).ready(function () {
var socket = io.connect('http://192.168.2.65:3000');
socket.on('test',function(msg){
$("#mediaContainer").append(msg);
console.log("i cant get this to work");
});
});
Thanks :)
Got it to work. Had to make a socket.emit inside the socket.on that catch it with another server javascript file like this:
index.js:
client.on('test',function(value){
io.sockets.emit('testi1',value);
});
app.js:
socket.on('testi1',function(msg){
$("#mediaContainer").append(msg + '<br /><br />');
});
There are two sides to socket.io, BackEnd and FrontEnd.
In the code above, you tried to manipulate the DOM like document.getElementById("mediaContainer").innerHTML = "Paragraph changed!";
but this is the FrontEnd part.
How socket.io works is you use js provided by socket in the FrontEnd to emit something to the server where the socket in the BackEnd will be listening to. Then, you emit something from BackEnd in response to the received emission. You also add a listener at the FrontEnd part to this BackEnd emission and finally manipulate the DOM according to the received emission.
FrontEnd
$(document).ready(function () {
var socket = io.connect('http://192.168.2.65:3000');
$("#button1").click(function(){
socket.emit('test',$("#someinput").val());
});
socket.on('test',function(msg){
$("#mediaContainer").append(msg);
});
});
BackEnd
io.on('connection', function(client) {
console.log('Client connected...');
client.on('test',function(msg){
// If you want all including the sender to get emission
client.emit('test', msg);
// If you want all excluding the sender to get emission
client.broadcast.emit('test', msg);
});
});
This should work. Cheers!!

Socket.io : Get Client sessionID at any point

I know how to retrieve the client sessionID when the user connects.
But I'd like to retrieve it at any time, for example when the client clicks on something, I would like to be able to know who clicked, what their sessionID was.
socket.sessionID doesn't work, nor does socket.handshake.sessionID
For example :
I have this express route :
.get('/result/:survey', function(req, res) {
res.redirect('/result/'+req.params.survey+'/1');
})
Just before the redirection, I'd like to make the user join a socket room, and also get their sessionID. How could I possibly do that ? According to the doc, it would be socket.join('room') but I doubt socketonly represents the connection I have with the client, and not with the other clients. Maybe I'm just having trouble understanding sockets !
As of version 1.0, you get the client's sessionid this way:
var socket = io();
socket.on('connect', function(){
var sessionid = socket.io.engine.id;
...
});
I'm not sure exactly what you mean, because "when the client clicks on something" assumes that you mean 'client-side' (where you can use socket.socket.sessionid) but "store it in an array of clients" assumes you mean 'server-side' (where you can access it as socket.id).
Client-side:
var socket = io.connect();
socket.on('connect', function() {
var sessionid = socket.socket.sessionid;
...
});
Server-side:
io.sockets.on('connection', function(socket) {
var sessionid = socket.id;
...
});
I store client id's in server side event handlers simply with:
// server.js
io.sockets.on('connection', function (client) {
client.on('event_name', function (_) {
var clientId = this.id;
}
}
I'm using socket.io version 2.0.4 and you can access the client id at any point in time by using this.id in a handler. For example:
socket.on('myevent',myhandler);
function myhandler(){
console.log('current client id: '+this.id);
}
Apparently the handler function is executed in the Socket context itself, which similarly will give you access to other self-properties like client (connected Client object), request (current Request object being processed), etc. You can see the full API here https://socket.io/docs/server-api/#socket

Categories