I currently have a working app utilizing passport.js authentication and socket.io for web sockets. It works fine via the http protocol, but as soon as I tell socket.io to listen to the https server, deserializeUser() fires for every connect event and no connection is made, no socket.io middleware is called.
HTTP (works):
var server = http.createServer(app).listen(port) //3000;
var io = require('socket.io').listen(server);
HTTPS (fails):
var httpsServer = https.createServer(sslOptions, app).listen(httpsPort)//8443;
//also attempted without any additional options supplied to io.listen()
var io = require('socket.io').listen(httpsServer, {
"log level": 3,
"match origin protocol" : true,
"transports" : ['websocket']
});
The client side:
var socket = io();
$('form').submit(function(){
socket.emit('chat message', $('#m').val());
$('#m').val('');
return false;
});
Socket.io middleware that should be responding (again, same middleware works when http server is supplied to io.listen()):
module.exports = function(app, io){
io.on('connection', function(socket){
console.log('base connection');
socket.on('chat message', function(msg){
console.log('message: ' + msg);
});
socket.on('disconnect', function(){
console.log('disconnect');
});
});
};
Do I have to specify protocol in the client somehow? I assume the io manager should use the url protocol. I also assumed passing "match origin protocol" : true as an option should use https. Any advice or assistance is appreciated.
EDIT:
The client throws a network error, net::ERR_INSECURE_RESPONSE
Related
I want my sockets to communicate securely. I think I'm requesting communication over https. So why is the secure flag always false? I've tried a bunch of different flag settings with no effect so far.
Sample site developed on glitch.com here: https://glitch.com/edit/#!/sponge-tablecloth.
Landing page is here: https://sponge-tablecloth.glitch.me/
Client page code:
<div id="div"></div>
<script src="/socket.io/socket.io.js"></script>
<script>
socket = io("https://sponge-tablecloth.glitch.me/");
socket.on('message', function(message) { div.innerHTML += message + "<br>"; });
</script>
Node.js server code:
var express = require('express');
var app = express();
let http = require('http').Server(app);
app.use(express.static('public'));
app.get("/", function (request, response) {
response.sendFile(__dirname + '/views/index.html');
});
let io = require('socket.io')(http);
io.on('connection', function(socket) {
console.log("checking connection, secure: " + socket.handshake.secure);
io.emit('message', "checking a connection, secure: " + socket.handshake.secure);
});
let listener = http.listen(process.env.PORT, function(){
console.log('Your app is listening on port ' + listener.address().port);
});
Problem is most likely that a reverse proxy is terminating TLS before proxying the requests to your application. It is common to have a setup that looks like this:
User -[HTTPS]-> Nginx(terminate TLS) -[HTTP]-> Application
This means that your application thinks that the transport was always insecure, while in fact it's just been terminated by the proxy (in this case Nginx). Glitch.io likely does this exact thing since your application is only offering insecure HTTP connections.
If you want end-to-end encryption you need to use the https package from stdlib instead of the http package, and setup certificates.
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.
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
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>
I'm relatively new to node.js and it's addons, so this is probably a beginnersquestion.
I'm trying to get a simple HTML page on a webserver connect to a different server running node.js with websocket.io.
My code looks like this:
Client
<script src="socket.io/socket.io.js"></script>
<script>
// Create SocketIO instance, connect
var socket = new io.Socket();
socket.connect('http://127.0.0.1:8080');
// Add a connect listener
socket.on('connect',function() {
console.log('Client has connected to the server!');
});
// Add a connect listener
socket.on('message',function(data) {
console.log('Received a message from the server!',data);
});
// Add a disconnect listener
socket.on('disconnect',function() {
console.log('The client has disconnected!');
});
// Sends a message to the server via sockets
function sendMessageToServer(message) {
socket.send(message);
};
</script>
Serverside
// Require HTTP module (to start server) and Socket.IO
var http = require('http');
var io = require('socket.io');
var port = 8080;
// Start the server at port 8080
var server = http.createServer(function(req, res){
// Send HTML headers and message
res.writeHead(200,{ 'Content-Type': 'text/html' });
res.end('<h1>Hello Socket Lover!</h1>');
});
server.listen(port);
// Create a Socket.IO instance, passing it our server
var socket = io.listen(server);
// Add a connect listener
socket.on('connection', function(client){
console.log('Connection to client established');
// Success! Now listen to messages to be received
client.on('message',function(event){
console.log('Received message from client!',event);
});
client.on('disconnect',function(){
clearInterval(interval);
console.log('Server has disconnected');
});
});
console.log('Server running at http://127.0.0.1:' + port + '/');
Starting up the server works fine and running http://localhost:8080 in my browser also works, returning 'Hello Socket Lover' as expected. But I want to make a different page talk to the sockets, not run one from node.js.
But when I run it, nothing happens and the Chrome console returns:
Failed to load resource http://undefined/socket.io/1/?t=1333119551736
Failed to load resource http://undefined/socket.io/1/?t=1333119551735
I've been at this all day. Any help?
Have you tried loading the socket.io script not from a relative URL?
You're using:
<script src="socket.io/socket.io.js"></script>
And:
socket.connect('http://127.0.0.1:8080');
You should try:
<script src="http://localhost:8080/socket.io/socket.io.js"></script>
And:
socket.connect('http://localhost:8080');
Switch localhost:8080 with whatever fits your current setup.
Also, depending on your setup, you may have some issues communicating to the server when loading the client page from a different domain (same-origin policy). This can be overcome in different ways (outside of the scope of this answer, google/SO it).
You need to make sure that you add forward slash before your link to socket.io:
<script src="/socket.io/socket.io.js"></script>
Then in the view/controller just do:
var socket = io.connect()
That should solve your problem.
Instead of:
var socket = new io.Socket();
Try:
const socket = io();
Also add a server file:
const http = require('http');
const express = require('express');
const app = express();
const server = http.createServer(app);
app.use(express.static(__dirname + '/public'));
const io = require('socket.io')(server);
const PORT = 5000;
server.listen(PORT, () => {
console.log(`Server is Listening On Port ${PORT}`);
});