socket.io authentification not working on first connection - javascript

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

Related

Connection to nodejs (express) refused

I’m a long term programmer, but haven’t used nodejs much in my code. Now I need to use it in my current code and I’ve ran into a problem that I can’t seem to figure out myself, I have googled a lot but nothing seem to fix it.
I am trying to get my website to connect to the nodejs server running on same host.
If I visit the url in my browser, it works fine (http://localhost:6857/socket.io/?EIO=4&transport=polling) and I see this respond
0{"sid":"s_v860SbNO4toknPAAAA","upgrades":["websocket"],"pingInterval":25000,"pingTimeout":20000}
But when I try to connect thru the website, I just get
GET http://localhost:6857/socket.io/?EIO=3&transport=polling&t=N_gL_HZ net::ERR_CONNECTION_REFUSED
Can someone guide my in the right direction for how to fix this, so I can begin using nodejs inside my website?
This is my server.js
// use express
var express = require("express");
// create instance of express
var app = express();
// use http with instance of express
var http = require("http").createServer(app);
// start the server
var port = 6857;
http.listen(port, '0.0.0.0', function () {
console.log("Listening to port " + port);
});
// create socket instance with http
var io = require("socket.io")(http);
// add listener for new connection
io.on("connection", function (socket) {
// this is socket for each user
console.log("User connected", socket.id);
});
io.on("connect_error", (err) => {
console.log(`connect_error due to ${err.message}`);
});
And this is my JS code inside my website
<script>
var server = "http://localhost:6857/";
var io = io(server);
</script>
Socket IO requires you to enable CORS explicitly - Thus why you get the error stated above.
To enable CORS, please see the following link

Why is a connection not created for this simple websocket snippet?

I have a simple snippet on the front end as follows which I can verify is working. I can do this by changing the port to something other than 3000 and it will error.
It is definitely finding the server at that port:
// Create WebSocket connection .. will error if I change the port
const socket = new WebSocket('ws://localhost:3000');
console.log('DEBUG: Web socket is up: ');
// Connection opened
socket.addEventListener('open', function (event) {
socket.send('Hello Server!');
});
I am using ws-express on the server side as follows. This was the minimal example given in the NPM docs:
const expressWs = require('express-ws')(app);
app.ws('/echo', (ws, req) => {
ws.on('message', (msg) => {
ws.send(msg);
});
});
However, the open event on the client never fires. I would like to send messages from the client to the server, but I assume, that I need an open event to fire first.

Client not receiving message from server

Hi i have a node js server and im using sockets to communicate.
Index:
<script src="socket.io/socket.io.js"></script>
Client JS:
var socket = io.connect("http://localhost:8081");
socket.on('hi', function(data){
console.log("g");
console.log(data);
});
So it seems to connect just fine to the server. I have a socket called 'hi' waiting for any incoming messages. I added 2 console logs incase data was null, it would still print something to the console.
Server:
var express = require("express");
var app = express();
var server = require("http").Server(app);
var io = require("socket.io")(server);
var mazeGenerator = require("generate-maze");
app.use(express.static("public"));
io.on("connection", function(socket) { // EDITED
console.log("A player has connected - sending maze data...");
socket.emit("hi", "hi");
});
So when i refresh the page, the client connects and in my CMD i see the "A player has connected..." console log. From then on, its blank from the server or client, I can keep refreshing and it will keep saying a player has connected by the clients console stays blank
Since the connection is proven to be established, I suspect this is an issue of a way you emit the data. Your second parameter hi may not be taken as a data to be transmitted, according to
https://socket.io/docs/server-api/#socket-emit-eventname-args-ack
In my understanding, socket.io emit Object instead of String so can you try this?
io.on("connection", function(socket) {
console.log("A player has connected - sending maze data...");
socket.emit("hi", {data: "hi"});
});

socket.io not emitting event from server to client on connection

I have a very basic setup with socket.io but am having trouble getting my server to send back a message once the connection has been established.
When a connection is established to my server, I want the server to send back a message to the client. I've tried to accomplish this with the following code:
Server
// Modules
var fs = require('fs');
var https = require('https');
// Certificate
var options = {
pfx: fs.readFileSync('<my cert>')
};
// Create Server
httpsServer = https.createServer(options);
// Create websocket
var io = require('socket.io')(httpsServer);
// Listen on a port
httpsServer.listen(4000,function() {
console.log('listening on *:4000');
});
io.on('connection', function(socket) {
console.log('a user connected');
socket.emit('test','you connected');
});
Client
var socket = io('https://<my server>:4000');
When I execute this code, the websocket gets established and my server console shows the message "a user connected". However, the message ['test','you connected'] does not get emitted through the socket.
The only way I've been able to get this to work is to use setTimeout() to wait 500ms before emitting the event, in which case it does work.
Why is that? How can I configure my server to automatically respond with a message as soon as the user connects?
You need to listen to the emitted event, using socket.on(event, callback);
<script src="https://cdn.socket.io/socket.io-1.4.5.js"></script>
<script>
var socket = io('https://localhost:4000');
//test is the emitted event.
socket.on("test", function(data){
console.log(data); //"you connected"
});
</script>

How can I establish one connection between a user and the WebSocket?

I have websocket running on a node/Express server.
I need to send json string back and fourth between a websocket and a client.
However, if a user opens more than one browser's tab, I like for the websocket server to know that this is the same user that is already connected.
Here is the logic execution order
A user connects to the WebSocket.
The user sends json string to the WebSocket.
The WebSocket does things to the received message.
WebSocket finally sends the new message to all the tabs that a user have open.
The new message should be returned only to that user not others.
How can I establish one connection between a user and the WebSocket?
This is my server setup
var env = require('./config');
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
var clients = [];
server.listen(env.socket.port, env.socket.host, function () {
var host = server.address().address;
var port = server.address().port;
console.log('Websocket running at http://%s:%s', host, port);
});
app.get('/', function (req, res) {
res.send('Welcome!');
});
io.on('connection', function (socket) {
clients[] = socket;
socket.emit('chat', { hello: 'world' });
socket.on('chat', function(msg){
console.log('message: ' + msg);
sendAll(msg);
});
});
function sendAll (message) {
for (var i=0; i< clients.length; i++) {
clients[i].send("Message For All: " + message);
}
}
If you do not have authentication for the users, then you need some browser-specific piece of data to correlate users on your backend.
I don't know about cookies (haven't used them), but one way at the JavaScript level would be to store a locally generated random ID (of sufficient length so that you don't have to worry about collisions) in local storage in the browser, and transmit this as part of the initial message at the WebSocket level.

Categories