I need to disconnect some users from server using this code:
socket.disconnect('User disconnected because of ....');
but when i handle the disconnect event on user side i don't see the disconnect reason
socket.on('disconnect', function(reason){
console.log('User 1 disconnected because '+reason);
});
I am using node for server side and browsers as client side, Any idea how to send a disconnect reason?
It seem there is no way to do such a thing like that but you can do the trick using emit function before closing the socket
Code in server side:
socket.emit('closeReason','User disconnected because of ....');
socket.disconnect();
Code in client side:
socket.on('closeReason',function(reason){ ... });
Related
I have the following code on my client side:
btn.addEventListener('click', function(){
socket.emit('chat',{
message: message.value,
handle: handle.value
});
});
So I think I understand the above. When a click event happens, run the callback function. Inside the callback function, have socket emit this "chat" event to the server. Along with the event socket emits, pass the JSON data.
Now on the server side we have this:
var io = socket(server);
io.on('connection', function(socket){
socket.on('chat', function(data){
io.emit('chat', data);
});
});
I think I understand this as well. Bind the socket to this server. Then listen to the connection event. When that event is invoked, socket.io (will magically?) pass a socket object to our function. We then listen to all of our sockets for a chat. As defined on the client side, take the data emited from the chat and emit it back to all of our sockets.
socket.on('chat', function(data){
// do cool stuff
})
Again in the above example, we have the client listening to the event on the server side.
My question is, how does the event get "passed" to the client side? Is this some sort of native Javascript functionality? I would like to know more of what happens on the backend.
The event gets passed to the server through websockets. Its a tcp connection from the browser to the server. The connection is full duplex meaning the server can send real time data to the client and vise versa.
In your frontend code you should have something that looks similar to
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
</script>
This code asks the server for a tcp connection using web sockets. Once the browser is connected to the server through websockets, socket.io can send events to the send through the connection.
The socket that is passed in the connection event is just a reference to whatever socket gets created when the frontend connects. The socket gets a unique id and with this reference you can communicate in real time to the web browser client.
If you want a deep dive into web sockets, I'd recommend reading this
https://www.rfc-editor.org/rfc/rfc6455
This question already has an answer here:
How can I let the javascript catch a signal from node and prompt a window right after that?
(1 answer)
Closed 5 years ago.
I noticed if I want to emit a message like
io.on('connection', function(socket){
socket.emit('signal')
})
Somehow I have to refresh the HTML page to get the ejs file work on the signal. But If I directly emit it like:
io.sockets.emit('signal')
Then I do not have to refresh the html to get the action work.
How come?
Let me translate the code in plain English.
First case
io.on('connection', function(socket){
socket.emit('signal')
})
Translation: When io is being connected, instruct the connected socket that triggered the connection event to emit 'signal'.
In this case, the io is attached with an event listener that listens for "connection" event, which is fired whenever a socket connects to the io. Therefore, whenever a socket connects to the io, the io instruct the socket to emit a "signal" event.
Why do I need to refresh for it to fire?
Because when you refresh, your computer acts as a socket and is connected to the io onload. Therefore a "connection" event is fired, and it is only fired when a socket connects to the io.
Note: Actually, you do not need to refresh to fire it. You can simply disconnect your internet connection and then reconnect it.
Second case
io.sockets.emit('signal')
Translation: All sockets that are currently connected to io, emit 'signal' event now!
In this case, you are instructing all currently connected sockets to emit the "signal" event. Your computer is a socket connected to the io, so it emits the event.
Note: If you have another device connecting to the same node server, and you use that command, you will see two "signal" events being emitted.
In the first case you're waiting for a "connection" event.
With a refresh of your page, you'll be connected again and finally fire your event.
In the second case, the message will be sent to all clients when you'll start your server.
Here
io.on('connection', function(socket){
}
listen for the connection event for incoming sockets.
if you directly use io.sockets.emit('signal') then you must need event on connection as it check for connection establish or not.
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.
I have an Android application and when somebody forces it to stop it doesn't fire the disconnect event on the server side.
Since I can't force people to update their android app, I can't make a ping event handler on the client side.
How could I check on the server side whether the client is active without client-side modification?
You need to find out why the disconnect event doesn't fire.
Have you put the socket's disconnect event inside the connection callback?
Also pay attention to variable io and socket. Maybe you put it wrong.
io.on('connection', function (socket) {
console.log('user connected');
socket.on('disconnect', function () {
console.log('user disconnected');
});
});
If the structure is already right, then I believe you should check the client's code.
I'm trying to detect whether the websocket is running before allowing clients to connect to it. Consider the following code:
var socket = io.connect('1.1.1.1:1234');
socket.on('connect',function() {
console.log('Client has connected to the server');
});
socket.on('disconnect',function() {
console.log("The client has disconnected from the server");
});
How can I make sure that this block is only called if the server on that IP is actually running and how can I output a message to the users stating that the server is not up?
Thank you
You would need to fire the io.connect() atleast once (consider this as a ping) to detect if server is up, but you can then handle the failure to connect with the socket.on('connect_failed', function () {}) event handler and show a message to user that the 'server is down'. Have a look at Exposed Events for the client
Further, if you would want to reduce the number of times the reconnect is attempted, you can change the socket.io configuration setting for 'reconnect' to false. Checkout Socket.io Configuration for more details