Socket IO keeps disconnecting and reconnecting - javascript

I'm very very new to sockets and socket.io, so I apologize if this is an obvious question. I'm using the C# client for Socket.IO and have a local javascript server running. Here is my app.js:
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
io.on('connection', function(socket) {
console.log('A user connected');
socket.on('test', function () {
console.log('Test run'); });
socket.on('disconnect', function () {
console.log('A user disconnected'); });
});
http.listen(3000, function() {
console.log('listening on localhost:3000'); });
In my main C# class (it is a Windows Forms application) the only line of code I have relating to the sockets at all is the instance variable private Socket socket = IO.Socket("http://localhost:3000/");. Yet for some reason, the server repeatedly receives the connect and disconnect events. Here is a screenshot of my console:
screenshot
This all happens automatically, as soon as I run my C# program, without any interaction, and stops as soon as I close it. Any ideas as to why it keeps connecting/disconnecting?
EDIT: For whatever reason the problem seems to go away when I remove Newtonsoft.json from the project. However, without it I cannot use the Emit function as well as others. Is there a workaround to this?

To anyone encountering this issue, check if client & server speak the same protocol version.
On a high-level, this is likely to be caused by protocol version mismatch between server and client. I've had the same issue in JS app. Turned out I was using some older version of socket.io on the client and the latest on the server. In the repository you provided we can find:
// EngineIoClientDotNet/Src/EngineIoClientDotNet.mono/Parser/Parser.cs
public static readonly int Protocol = 3;
So this (now deprecated) client is using Engine.IO protocol v3. You didn't provide info which socket.io version you were using on the server, but it simply might've been using different revision on Engine.IO protocol.
As a side note, speaking more low-level: I guess that the client might be able to connect, but it does not respond to server's first ping command in a proper way (or the other way around). Therefore the connection is immediately dropped. Socket.IO has a history of breaking changes in how ping-pong mechanism is implemented, and this might be the underlying root cause.

Related

socket.io - hundreds of requests instead of one connection

I created simple app to start with socket.io, but when I run it, Chrome(tested in other browsers, result same) eats all of my CPU and makes many requests:
I'm new to sockets, but I'm sure this is not how it should work. The code running in browser is really simple, it should just connect to socket and log all received data to console:
index.html
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.socket.io/socket.io-1.2.0.js" charset="UTF-8"></script>
</head>
<body>
<script type="application/javascript">
var Sockets = io.connect('http://localhost:4000');
Sockets.on('Test', function (data) {
console.log(data);
});
</script>
</body>
</html>
Also, my server file looks like this:
server.js
var app = require('express')();
var http = require('http').Server(app);
var bodyParser = require("body-parser");
var io = require('socket.io')(http);
var port = 4000;
http.listen(port, function () {
console.log('Server running at port ' + port);
});
var urlencodedParser = bodyParser.urlencoded({extended: false});
app.post('/', urlencodedParser, function (req, res) {
if (!req.body) return res.sendStatus(400);
var post = req.body;
io.emit("Test", post.data);
console.log(post.data);
res.send('true');
});
io.on('connection', function(socket){
console.log('a user connected');
socket.on('disconnect', function(){
console.log('user disconnected');
});
});
When I run the server node server.js, I got the Server running at port 4000 message and everything seems fine. But when I open the index.html in my browser, the node console is spammed by a user connected messages. Instead of connecting one client, the browser makes dozens of requests every second. When I close the browser, there is no output for some time, and then the node console is spammed by user disconnected messages.
This server should redirect all data sent via POST to connected sockets. When I make this POST request, the node server receives it (I know because it print's it into node console). But it's not received by the socket client, as there is no output in browser console (but the browser still makes dozens of new connections every second.
What is wrong here? First I thought I just messed up, so I went back and copy-pasted code from tutorial I found (not in English, but in Czech), but nothing changed. The tutorial has a lot of positive feedback, so there is propably something wrong with my computer. But what?
I had experienced the same issue, by following an example where the client was using the source of socket.io from this cdn: https://cdn.socket.io/socket.io-1.2.0.js
Tons of clients created whenever I tried to run the file (no matter if i just double clicked the html file, or if I put it under a web server, like IIS) . I then realized it might be an older version, and I just took the latest one released from this source: https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.4/socket.io.js
Everything works fine now.
Hope this helps
So to find what exactly was wrong, I downloaded example socket chat from socket.io website. When I runned it, I experienced exactly the same wrong behaviour - browser is opening many socket connections every second instead of keeping one.
So I deleted node_modules folder and used npm to install these modules again and whoa, it worked. So propably the files just corrupted during download or whatever it was, but doing the same procedure again was working this time.
Your configuration of running that page from a different web server than your socket.io server is on won't work as you have it. It will take one of three changes to make it work:
You can use the "same origin" for the web page and the socket.io connection by loading the web page from the same server that your socket.io. That means you need to load the web page directly from your socket.io web server.
You can configure your socket.io web server to accept cross origin connections (CORS connections).
You can configure your socket.io client to connect directly using webSocket without doing socket.io's usual preview with a regular http request.
If you're testing something you intend to deploy for real, you may as well just make your existing socket.io web server server your web page and load the web page directly from that.
Another possible cause of a situation like this is an incompatible client and server version of socket.io. You should make absolutely sure that you have the same version of socket.io on client and server. If you get the client socket.io library from /socket.io/socket.io.js from your socket.io web server, the the client version will automatically always match the server version. The way you are loading it from a CDN, you have to manually make sure you have identical versions.

JavaScript - ReferenceError: WebSocket is not defined

Focusing on the client side API only (because each server side language will have its own API), the following snippet opens a connection, creates event listeners for connect, disconnect, and message events, sends a message back to the server, and closes the connection using WebSocket.
// Create a socket instance
var socket = new WebSocket('ws://localhost:3000');
// Open the socket
socket.onopen = function(event) {
// Send an initial message
socket.send('I am the client and I\'m listening!');
// Listen for messages
socket.onmessage = function(event) {
console.log('Client received a message',event);
};
// Listen for socket closes
socket.onclose = function(event) {
console.log('Client notified socket has closed',event);
};
// To close the socket....
socket.close()
};
But I am getting an error on executing above snippet:
ReferenceError: WebSocket is not defined
I have gone through various links like https://davidwalsh.name/websocket, on how to implement WebSockets. But none of them are importing any npm package.
Question: So, how to implement WebSockets (client side AngularJS)? What am I missing here?
Try
const WebSocket = require('ws');
var socket = new WebSocket('ws://localhost:3000');
Then
npm i ws
and retry. It's work with my case
I'm leaving this here for people having trouble with the #stomp/stompjs package in a node app.
Add this line:
Object.assign(global, { WebSocket: require('ws') });
also, don't forget to npm install ws
The code you're referencing in your question is client-side code. WebSocket is available directly in browsers.
For your Node.js server-side code, look at the ws NPM package.
So, how to implement WebSockets (client side) on NodeJS?
You don't. Node.js is server-side, not client-side.
When you are trying to run JavaScript, usually, you run it either in Browser or in NodeJS.
Browser and NodeJS are different JavaScript runtime.
WebSocket itself is a application layer protocol, you need to use API to employ it.
Currently(05-Dec-2019),
most browsers support WebSocket API for developer to use WebSocket.
NodeJS does not provide any OOTB API for developer to use WebSocket, you need 3rd lib to use WebSocket (e.g. https://github.com/websockets/ws).
The example you followed is using WebSocket API in browser.
Hope it helps.

Jetty Web Socket Timeout

I am trying to establish a Web Socket Connection using Jetty 9.3.0 RC.
function checkDetails(port) {
var ws = new WebSocket("ws://localhost:9995/application");
ws.onopen = function(event) {
console.log("onopen called...");
}
ws.onerror = function(event){
console.log('onerror called...');
}
ws.onmessage = function(event) {
console.log("onmessage called..." + event.data);
}
ws.onclose = function(event) {
console.log("onclose called..." + port);
console.log(event);
ws.close();
}
}
The code works fine if the port 9995 used for creating the Web Socket connection is not occupied by some other process.
var ws = new WebSocket("ws://localhost:9995/application");
But in case if the port is occupied by some other process, then it keeps on trying to connect with that port until the port is released.
I need to provide a timeout so that if the port does not respond in 3 mins then the Web Socket should release (or stop listening) the port and display a console log.
Please let me know the simplest way to achieve this.
From client side you are connecting to some web socket. If port (9995 in your case) is available to connect to then it means that some program (in server mode) is listening and responding. And does something - answers with some data. So, you can connect to such program if it exists and answers or you cannot if there is no server listener for port 9995. When you say "port is occupied" by some other process that means that this process exist and answers. And this process will respond with whatever it is designed for. So, from client side, all what you do is connect to existing and running process which listens for this port in the server mode. That's it and that's all.
However, if we ignore your comment that OP is only about client side then my first suggestion would be to look on the server configuration and check that it is in multithread mode and can answer and proceed multiple requests at once. What you are describing looks like you have singe thread process which works with only one request and can answer next one when current is finished. That sounds like "process occupied". But since comment insist that we are talking only about client side then this speculation would be unnecessary.

unix sockets on nodeJs

Quick and basic nodeJs question,
I'm working with unix socket for inter-server communication between c++ application and my NodeJs server,
I've wrote my nodeJs server like so:
var net = require('net');
var unixSocketServer = net.createConnection('/tmp/unixSocket');
unixSocketServer.on('connect',function(){
console.log('unix server socket connected on /tmp/unixSocket');
...
});
However I'm getting connection refuse error.
I can understand that the c++ application haven't opened/connected to the socket yet.
My questions are
why does it matter? shouldn't the nodeJs server wait until 'connect' event emitted?
Am I using nodeJs currently? am I missing something?
Ok, so there's some misunderstanding here. Let's start from what a 'unix socket' really is. I think you're thinking it's just a file-like item that acts like a server on its own through the OS/filesystem. That's not quite correct. While it is indeed bound through the filesystem, it isn't really a traditional file. Instead, it's just like an TCP/IP socket, except instead of binding an IP and port, a filepath is bound.
The key point there is that it's just a bound socket with a different type of address (and some extra capabilities, but that's outside the scope here). So that means that something has to bind the socket! In this case, we need a server, just like we would if we were communicating over a 'normal' port. If there isn't a server bound to the path, you get an error, just like you would when connecting to a port with no listener.
To create a server on a unix domain socket in node, it's pretty simple:
'use strict';
const net = require('net');
const unixSocketServer = net.createServer();
unixSocketServer.listen('/tmp/unixSocket', () => {
console.log('now listening');
});
unixSocketServer.on('connection', (s) => {
console.log('got connection!');
s.write('hello world');
s.end();
});
Note that there is one other difference between 'normal' sockets and unix domain sockets: After a server is done with the unix domain socket, it is not automatically destroyed. You must instead unlink /tmp/unixSocket in order to reuse that 'address'/path

WebSocket not connecting to socket.io

I am using Node.js with socket.io to implement websockets in one of my pages. server.js (what Node.js runs) has this code:
var http = require("http").createServer(),
io = require("socket.io").listen(http);
http.listen(8080);
io.sockets.on("connection", function(socket) {
socket.emit("message", {hello:"world"});
});
And this is the code I'm trying to connect with:
var socket = new WebSocket("ws://92.60.122.235:8080/");
socket.onopen = function() {
alert("Socket has been opened!");
}
When I load the page, nothing happens. I'm using Chrome, and I know websockets are supported. No errors are present in the error console, and if I watch socket.io serving requests from command line I don't see any user connecting.
As far as I know this should work, could anyone explain what could be going wrong?
You need a socket.io client to pass some authentication phases I believe. Try this, and it should work(the client javascript is served by socket.io itself, don't worry about it).
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost');
socket.on('message', function (data) {
console.log(data);
socket.emit('helloworld', { msg: 'why do you so love to say hello world?' });
});
</script>
From http://socket.io/#faq
Why not just call it WebSocket if the actual WebSocket is not
present and mimick its API?
Socket.IO does more than WebSocket, even
if WebSocket is selected as the transport and the user is browsing
your website with an ultra modern browser. Certain features like
heartbeats, timeouts and disconnection support are vital to realtime
applications but are not provided by the WebSocket API out of the box.
This is akin to jQuery's decision of creating a feature-rich and
simple $.ajax API as opposed to normalizing XMLHttpRequest.
You can download the webpage source code that runs in Chrome, Firefox, and IE (at least) via the blog article "Websocket Server Demonstration" from the High Level Logic Project. The webpage is set up for developers.

Categories