Node.js - Socket.io repeats the 'io.on('connection') over and over - javascript

So, I am still in the experimental phase of Socket.io, but I just can't figure out why my code is doing this. So, I have the code below and when I console.log the code, it repeats the the connection even when there is only one connection. Do you know a solution?
io.on('connnection', (socket) => {
console.log("A new user is connected.")
})
Client side:
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io()
</script>
Node.js Console:
A new user is connected.
A new user is connected.
A new user is connected.
A new user is connected.
A new user is connected.
A new user is connected.
A new user is connected.
...
(Note: there is only one connection, and I have already cleared the browser cashe)

Here are some of the possible reasons for socket.io connecting over and over:
Your socket.io client and server versions do not match and this causes a connection failure and an immediate retry.
You are running with some infrastructure (like a proxy or load balancer) that is not configured properly to allow lasting webSocket connections.
You are running a clustered server without sticky webSocket connections.
You have put the server-side io.on('connnection', ...) code inside some other function that is called more than once causing you to register multiple event handlers for the same event so you think you're getting multiple events, but actually you just have multiple listeners for the one occurrence of the event.
Your client code is calling its var socket = io() more than once.
Your client page is reloading (and thus restarting the connection on each reload) either because of a form post or for some other reason.
FYI, you can sometimes learn something useful by installing listeners for all the possible error-related events on both client and server connections and then logging which ones occur and any parameters that they offer. You can see all the client-related error events you can listen to and log here.

To solve repetion problem write your code like that for socket:
io.off("connnection").on('connnection', (socket) => {
console.log("A new user is connected.")
})

Related

How do I use a single connection with socket.io

I am making a real time multiplayer game with socket.io and node.js, I have a html file that runs a public script to connect to the server and run commands, as well as defining the library I need with
<script src="https://code.jquery.com/jquery-2.2.2.min.js"></script>
I have a connect and disconnect function in thew public js file that has these functions:
// send join request
function joinlobby(room) {
socket.emit("userJoined", room);
}
// emit when a player leaves
function leavelobby(room) {
socket.emit("userLeft", room);
}
and whenever I create a new socket within the function with something like
// emit when a player leaves
function leavelobby(room) {
let socket = io();
socket.emit("userLeft", room);
}
it will run correctly, however with both having a separate connection it causes issues. I was trying to have them use the same connection by having let socket = io(); placed above the functions to use the same socket, however when the program hits that line it stops running the file without throwing an error
How could I use a single connection to the server, and/or why is the program disconnecting when I define the socket outside a function?
Edit for clarity:
The issue isn't wanting a single connection for every client, but rather each client has multiple connections whenever I define the socket in each respective function. I am aiming at only having 1 connection for each client but the line throws an error
I'm sorry for the ambiguity, I'm new to asking questions on here
When you create a connection to the socket server each client will have his own connection, if you want to send a single message to multiple clients you should use rooms. It is pretty easy to use:
io.on("connection", socket => {
socket.join("room1");
});
If boot clients are connected to the same room you will be able to send a message to that room.
io.to("room1").emit("Hello every body");
More info here: https://socket.io/docs/v3/rooms/

What is actually the default behavior of socket.io?

I'm using socket.io on the client as well as on the server side. It is a great library, but I must say that the default behavior is not described in the docs, which make using the library so confusing. At least I didn't find any references for the default behavior.
Basically, I watched tutorials, where a basic chat app was build with socket.io. In the tutorials, the server send a message automatically to all connected clients. Is this the default behavior in the server side?
I'm not sure about this. I'm developing an app where the user can (un)subscribe to specific topics and receive values from the server. Let's say I have two topics (topic1 and topic2). I opened two clients (client1 and client2) and I subscribed to topic1 from client1. I noticed that I received the value1 of topic1 in client1 but client2 received nothing.
const io = require('socket.io')(3000); // create server
io.on('connection', socket => {
console.log("client is connected over sockets");
socket.on('subscribe', () => {socket.emit('send-msg', "send to client");})
});
In this case above, will the server send to all clients or to only one client? What is the default behavior of socket.io?
PS: Another thing I noticed about socket.io is that there is many ways to do the same thing and it is not documented well. Like for example, I'm instantiating a client with socketIOClient function: const socket = socketIOClient("my_host") But I've seen many tutorials that uses the openSocket function or even directly the io function (here for some reason the author added this in the html <script defer src="http://localhost:3000/socket.io/socket.io.js"></script>).
All these function do the same thing, right?
You're looking at the difference between namespace.emit and socket.emit. A socket is one specific connection, and emitting an event on it sends it only to that one connection. A namespace on the other hand is a group of several sockets, and emitting an event on it emits it to every socket in the group. The entire io server is one namespace by default, so io.emit(...) sends a message to all connected clients. You can group your sockets into arbitrary namespaces and rooms to make it easy to send messages to selected groups.

why does socket.io client emit trigger its own listener...even if server is offline?

I ran into a weird problem when using socket io after many years.
Years ago, I could use the following code on client side
socket.emit('user', {userId: 2});
// and somewhere else in the code id listen for incoming 'user' replies
socket.on('user',(reply) => {
// do something with user data received from server
});
Now, when I have the same code on the client side, and I emit "user" request, the socket.on('user') callback is immediately fired with request payload which was supposed to go to the server( which is offline ).
I thought socket.on() listeners were triggered only by replies from the server and not by the outgoing messages from the client itself.
Is the socket.io supposed to work like this or am i missing something in configuration?
I think I solved this by accidentally stumbling on another post about how socket.io keeps the connection alive.
The socket.emit('user', {userId: 2}); was an example.
In my real app, I used the event name "ping" which seems to be reserved by socket.io.
The client keeps pinging and listening to pings constantly.
So, when I added my own socket.on('ping') listener, it hooked into socket.io internal ping/pong system. ( at least i think thats the case )

detect socket.io disconnect and destroy events client side

I have html page sent by node.js server and socket.io component that connects to that server like this:
var socket = io();
Also several socket events:
socket.on('server-message', function(type, content) {
...
});
socket.on('server-update', function(type, content) {
...
});
The problem is that in the moment server is stopped, i get client side errors:
https://example.com/socket.io/?EIO=3&transport=polling&t=LptmQyC net::ERR_CONNECTION_REFUSED
Once server is started again it crashes in a 30 seconds after.
It looks like i could use a detection if server is not available anymore and just destroy all socket related events, then reconnect by page refresh or some button.
Maybe someone could help me with this.
I dont believe that much can be done about the error, its internal socket.io error that is a result of unsuccessful server polling.
For better understanding, once connection is severed, socket.io goes into ajax polling and will try to reconnect as soon as possible (meaning as soon as server is up again).
Server crash after reconnect on the other hand can be addressed very easy. The code you presented is only functional in terms of how to connect, you are missing handlers for disconnect and optionally - reconnect.
I will show you how you can add to this code to manage disconnects (and prevent server crashes after bringing it back up).
First of all connect to server:
var socket = io();
Create a disconnect event right after (btw its also a code for server side disconnect event):
socket.on('disconnect', function() {
destroy_socket_events();
});
Create function that will destroy all your listeners:
var destroy_socket_events = function() {
socket.off('disconnect');
socket.off('server-message');
socket.off('server-update');
// add all other socket events that you have in here ...
};
Now what is going to happen is this:
connection is made
server is stopped
client triggers disconnect event
function destroys all of your socket listeners
server is back up
client reconnects (socket.io will do it because of the polling)
no listener is ever triggered at that point
So you can safely reinitialize all of your code and attach listeners again properly.

What's the complexity of connecting and disconnecting with socket.io?

I'm running a node.js server. On my website I use different URLs for different pages. For instance:
mydomain.com/ -- Index
mydomain.com/register -- Register
mydomain.com/profile -- Profile
I am using socket.io to send chat messages and notifications to the client. However, whenever the user switches page or performs a POST-request the socket connection is disconnected and then reconnected.
I'm wondering what the complexity of socket.io's connect/disconnect functions are and wether it is durable that all clients reconnect their sockets each time they perform an action on my website? I've looked at the documentation for socket.io without finding the answer.
That's what I have found, but I would guess it would really depend on your code. If each page connects to the channel then the connection will be reestablished. I am also in the habit of storing messages on the server side to reestablish state - something to this effect:
const events = []
const onSomeEvent = function(myEvent) {
events.push(myEvent)
socket.emit("onSomeEvent", myEvent)
}
socket.on("connect", function(){
events.forEach(function(myEvent){
socket.emit("onSomeEvent", myEvent)
})
})

Categories