socket.io - 'connect' event does not fire on the client - javascript

I am trying to get started with node.js and socket.io.
I have a very (very) simple client-server test application and i can't get it to work.
The system is set up on a windows machine with an apache server.
The apache is running on port 81 and the the socket.io is set up to listen to port 8001
Server - server.js
var io = require('socket.io').listen(8001);
io.sockets.on('connection', function (socket) {
console.log('\ngot a new connection from: ' + socket.id + '\n');
});
Client - index.html
<!DOCTYPE html>
<html>
<head>
<title>node-tests</title>
<script type="text/javascript" src="http://localhost:8001/socket.io/socket.io.js"> </script>
<script type="text/javascript">
var socket = io.connect('http://localhost', { port: 8001 });
socket.on('connect', function () {
alert('connect');
});
socket.on('error', function (data) {
console.log(data || 'error');
});
socket.on('connect_failed', function (data) {
console.log(data || 'connect_failed');
});
</script>
</head>
<body>
</body>
</html>
After starting my server using node server.js the standard (expected) output is written to the server console:
info: socket.io started
When I open index.html in the browser (chrome in my case - didn't test on other browsers) the following log is written to the server console:
info: socket.io started
debug: served static content /socket.io.js
debug: client authorized
info: handshake authorized 9952353481638352052
debug: setting request GET /socket.io/1/websocket/9952353481638352052
debug: set heartbeat interval for client 9952353481638352052
debug: client authorized for
got a new connection from: 9952353481638352052
debug: setting request GET /socket.io/1/xhr-polling/9952353481638352052?t=1333635235315
debug: setting poll timeout
debug: discarding transport
debug: cleared heartbeat interval for client 9952353481638352052
debug: setting request GET /socket.io/1/jsonp-polling/9952353481638352052?t=1333635238316&i=0
debug: setting poll timeout
debug: discarding transport
debug: clearing poll timeout
debug: clearing poll timeout
debug: jsonppolling writing io.j[0]("8::");
debug: set close timeout for client 9952353481638352052
debug: jsonppolling closed due to exceeded duration
debug: setting request GET /socket.io/1/jsonp-polling/9952353481638352052?t=1333635258339&i=0
...
...
...
In the browsers console I get:
connect_failed
So it seems like the client is reaching the server and trying to connect, and the server is authorizing the handshake but the connect event is never fired in the client, instead the connect method reaches its connect timeout and max reconnection attempts and gives up returning connect_failed.
Any help\insight on this would be helpful.
Thank you

Make sure that both client and server have same major version of socket.io. For example, combination of socket.io#2.3.0 on server and socket.io-client#3.x.x at client leads to this case and the 'connect' event is not dispatched.

//Client side
<script src="http://yourdomain.com:8001/socket.io/socket.io.js"></script>
var socket = io.connect('http://yourdomain.com:8001');
//Server side
var io = require('socket.io').listen(8001);
io.sockets.on('connection',function(socket) {
`console.log('a user connected');`
});
Client side:
The client side code requests the client version of socket IO from the same file that gives you server side socketIO. Var socket will now have all the methods that are available with socketIO, such as socket.emit or socket.on
Server Side:
same as client side, making the socketIO methods available for use under var io.

Change in the frontend (client):
var socket = io.connect(http://myapp.herokuapp.com);
to
var socket = io.connect();
After many hours of dealing with various clients (Chrome, Firefox browsers and Phonegap app) that did not register connection to the server properly (i.e. the server registered the websocket connection successfully in its logs, but the frontend did not register the connection event), I tried #Timothy's solution from the comments and now everything works again on heroku and on localhost.

With socketio 2.3.0 you have to use socket.on('connect')
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io({
transports: ['polling']
});
console.log("created",socket);
socket.on('connect', function(data){ // <-- this works
console.log("socket ON connect",data);
});
socket.on('connection', function(data){ // <-- this fails
console.log("socket ON connection",data);
});
</script>

Use autoConnect: false option while creating: io(... { autoConnect: false }), subscribe on your events and invoke io.connect().

Try the following:
Change
var socket = io.connect('http://localhost', { port: 8001 });
to
var socket = io.connect('http://localhost:8001');

Try using this:
Server.js
var http = require("http").createServer(), io = require("socket.io").listen(http);
http.listen(8001);
io.sockets.on("connection", function(socket){
console.log("Connected!");
socket.emit("foo", "Now, we are connected");
});
index.html
<script src="http://localhost:8001/socket.io/socket.io.js"></script>
<script>
var i = io.connect("http://localhost:5001");
i.on("foo", function(bar){
console.log(bar);
})
</script>

Related

Does socket IO need to serve HTML to work?

So, I am quite puzzled. I have a socket IO server that runs OK, and the HTML web client does connect to it. But, I can't emit anything. I'm using xampp to serve webpages, but does socket IO need to serve content for it to receive and send data? It's weird that I connect OK,but that's it, no emit function works.
Here's my code..
var io = require('socket.io')();
io.on('connection', function(client){ console.log("Connected OK."); io.emit('message',"data"); });
io.on('message', function(client){ console.log(client); });
io.listen(8080);
HTML
<script src="http://localhost:8080/socket.io/socket.io.js"></script>
<script>
// Create SocketIO instance, connect
var socket = io.connect('http://localhost:8080');
// Add a connect listener
socket.on('connect', function() {
alert('Client has connected to the server!');
});
socket.on('message', function(event) {
console.log('Received message from client!', event);
});
</script>
The code above prints "Connected OK" to the NPM console, and it alerts "Client has connected to the server!", but that's it. So my question is, does the NPM server need to serve the HTML to work, or am I doing things wrong?. I use xampp because of PHP and MySQL.
UPDATE:## The server sends to client just fine, and the client tries to send data back, and the server receives the packet. But then it reports: " engine:polling transport discarded - closing right away +0ms". Is this normal?

Can I connect to socket.io server using generic method?

I have a node.js server and I attached socket.io listener to it. The code is like this.
const server = new Hapi.Server();
server.connection({
"port": config.port
});
let io = socketio(server.listener);
io.on("connection", function(socket) {
console.log("A user connected");
socket.on("disconnect", function(){
console.log("A user disconnected");
});
// receive message from client
socket.on("client-server", function(msg) {
console.log(msg);
});
});
// somewhere to emit message
io.emit("server-client", "server to client message");
Normally I use the standard way to connect to the websocket server. An example is like this:
<!DOCTYPE html>
<html>
<head><title>Hello world</title></head>
<script src="http://localhost:3000/socket.io/socket.io.js"></script>
<script>
var socket = io();
socket.on('server-client', function(data) {document.write(data)});
socket.emit('client-server', 'test message');
</script>
<body>Hello world</body>
</html>
It works without issue. Now, my colleague wants to connect to the websocket server from his FME server. Based on his research, the only way he can use to connect to a websocket server is using a url like this:
ws://localhost:3000/websocket
My question is: is there a way to connect to socket.io server listener using this type of string?
If not, is there a way to create a websocket server with ws://host:port url and also attach it to my node.js server?
Or, is there a way to connect to socket.io listener in FME server?
To tell Socket.IO to use WebSocket only, add this on the server:
io.set('transports', ['websocket']);
And on the client add this:
var socket = io({transports: ['websocket']});
Now you can only connect to the WebSocket server using ws protocol.

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 handle request disconnect in node/express app

I have an express/node app and I would like to capture when there is an unexpected interruption in the connection. I tried the following:
req.on('close', function () {
//this captures the browser/tab close scenarios
})
My code does not work in the following scenerios:
Wifi is disconnected
Device shuts down due to lack of power
Is there an event handler that could be leveraged in these scenarios?
You could use sockets to accomplish this. Socket.io is popular.
var io = require('socket.io')({
'port': 8000,
'heartbeat interval': 2000,
'heartbeat timeout' : 3000
});
io.listen(server);
var app_socket = io.of('/foo');
app_socket.on('connection', function(socket) {
// BROWSER CONNECTED
socket.on('disconnect', function(){
// BROWSER DISCONNECTED
});
});
The disconnect event will fire whenever the client loses connection. To connect on the client side it would look like this:
<script media="all" src="/socket.io/socket.io.js"></script>
<script type="text/javascript">
var socket = io.connect('/foo');
socket.on("connect", function(){
// CONNECTED TO SERVER
});
</script>

Why isn't my hello world node.js tcp server getting any connections?

I'm trying to test out Node.js and I'm using this code:
// Load the net, and sys modules to create a tcp server.
var net = require('net');
var sys = require('sys');
// Setup a tcp server
var server = net.createServer(function (socket) {
// Every time someone connects, tell them hello and then close the connection.
socket.addListener("connect", function () {
//sys.puts("Connection from " + socket.remoteAddress);
console.log("Person connected.");
var myPacket = [1,2,3,4,5];
sys.puts(myPacket);
socket.end("Hello World\n");
});
});
// Fire up the server bound to port 7000 on localhost
server.listen(7000, "localhost");
// Put a friendly message on the terminal
console.log("TCP server listening on port 7000 at localhost.");
To send a byte array to any connections that show up on port 7000 of local host. Nothing is connecting though, I've tried firefox (localhost:7000, and 127.0.0.1:7000) I tried PuTTy, and even writing my own Java TCP Client to connect to local host, but nothing is working, so I'm convinced that the code is wrong.
Can someone please tell me why my code won't allow connections?
You seem to be overcomplicating the connection part. The callback with the socket is already the connection event so you don't need to listen to it separately. Also, if you want to send binary, use the Buffer class. Here's your code changed. Remember to set your mode to telnet in putty when connecting. I've also changed the end() to write() so it doesn't auto close the connection.
// Load the net, and sys modules to create a tcp server.
var net = require('net');
var sys = require('sys');
// Setup a tcp server
var server = net.createServer(function (socket) {
//sys.puts("Connection from " + socket.remoteAddress);
console.log("Person connected.");
var myPacket = new Buffer([65,66,67,68]);
socket.write(myPacket);
socket.write("Hello World\n");
});
// Fire up the server bound to port 7000 on localhost
server.listen(7000, "localhost");
// Put a friendly message on the terminal
console.log("TCP server listening on port 7000 at localhost.");

Categories