NodeJS Websocket client stay in pending mode - javascript

i have a simple js script that "try" to connect to listening server (SocketTest) as shown in the image below. It's really simple, just one line :
var exampleSocket = new WebSocket('ws://127.0.0.1:6601');
So, yes, it is connected but it stay in pending mode finishing by "failed: WebSocket opening handshake timed out"
Maybe i'm wrong somewhere but i don't see it... and it's really simple.
If someone got an idea....
Thanks in advance.

Without implementing open event do not expect any answer from the server :)
Try this:
const WebSocket = require('ws');
const ws = new WebSocket('ws://127.0.0.1:6601');
ws.on('open', function open() {
ws.send('something');
});
Edit: The nodejs tag fooled me I thought it is server side.
The same true on client side, you need to handle onopen event:
// Connection opened
exampleSocket.addEventListener('open', function (event) {
socket.send('Hello Server!');
});
// Listen for messages
exampleSocket.addEventListener('message', function (event) {
console.log('Message from server ', event.data);
});

Related

clientside nodejs readline not triggering 'close' event except on CTRL-C from server

I am trying to make a simple server/client TCP connection with javascript using nodejs.
I have client.js code (which I can't modify) which has this line:
var s = net.connect({port: this._port}),
rl = readline.createInterface({input: s});
s.write('quit\r\n');
rl.on('close', () => done(null, output));
The problem is, I cannot get that event to trigger. On the server side, I have
socket.once("close", function () {
console.log("Connection from %s closed", remoteAddress);
// socket.destroy();
});
socket.once("end", function() {
console.log("Ending connection");
// socket.destroy();
})
The server side receives an end event, and prints it out, followed by the close. However, I can't seem to get that client to get that end event naturally. Something weird that does work though, is if I CTRL+C the server and stop it midway. That causes the client to get the 'end' and move on with the code. As of now, it just timeouts. Now I am wondering if it's possible to automatically send a CTRL+C or if there is any other way to get this 'end' to trigger.
Methods I have tried:
socket.destroy(), sending EOT character.
Again, I cannot modify this client.js.

How to catch and deal with "WebSocket is already in CLOSING or CLOSED state" in Node

I've been searching for a solution to the issue "WebSocket is already in CLOSING or CLOSED state" and found this:
Meteor WebSocket is already in CLOSING or CLOSED state error
WebSocket is already in CLOSING or CLOSED state.
Answer #1 is for strictly related to Meteor and #2 has no answers... I have a Node server app with a socket:
const WebSocket = require('ws');
const wss = new WebSocket.Server({ server });
wss.on('connection', function connection(socket) {
socket.on('message', function incoming(data) {
console.log('Incoming data ', data);
});
});
And clients connect like this:
const socket = new WebSocket('ws://localhost:3090'); //Create WebSocket connection
//Connection opened
socket.addEventListener('open', function(event) {
console.log("Connected to server");
});
//Listen to messages
socket.addEventListener('message', function(event) {
console.log('Message from server ', event);
});
However after a few minutes, clients randomly disconnect and the function
socket.send(JSON.stringify(data));
Will then throw a "WebSocket is already in CLOSING or CLOSED state.".
I am looking for a way to detect and deal these disconnections and immediately attempt to connect again.
What is the most correct and efficient way to do this?
The easiest way is to check if the socket is open or not before sending.
For example - write a simple function:
function isOpen(ws) { return ws.readyState === ws.OPEN }
Then - before any socket.send make sure it is open:
if (!isOpen(socket)) return;
socket.send(JSON.stringify(data));
You can also rewrite the send function like this answer but in my way you can log this situations.
And, for your second request
immediately attempt to connect again
There is no way you can do it from the server.
The client code should monitor the WebSocket state and apply reconnect method based on your needs.
For example - check this VueJS library that do it nicely. Look at Enable ws reconnect automatically section
Well, my answer is simple, is just you send message to the web socket in an interval of time, to understand that you are using the service. It is better than you got another connection. Now, you start your project where are the web socket function and inspect elements to see the state Time, and see the time that change of "pending" for the time when closes. So now you will define a media of interval to make a setInterval functions like this for example: enter code here
const conn = WebSocket("WSS://YourLocationWebSocket.com");
setInterval(function(){
var object = {"message":"ARandonMessage"};
object = JSON.stringify(object);
conn.send(object);
},/*The time, I suggest 40 seconds, so*/ 40000)
might be late to the party, but i recently encountered this problem & figured that the reason is because the readystate property of the websocket connection is 3 (CLOSING) https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/readyState at the time the message was sent.
i resolved this by checking the readystate property; if it equals to 3, close and reinitialize the websocket connection. then do a while loop that exits when the readystate property equals to 1, otherwise a delay, to ensure that the new connection is already open.
if ( this.ws.readyState === 3 ) {
this.ws.close();
this.ws = new WebSocket(`wss://...`);
// wait until new connection is open
while (this.ws.readyState !== 1) {
await new Promise(r => setTimeout(r, 250));
}
}
this.ws.send(...)

Socket.io Client Fire Event if Can't connect to server

I'm running a simple node.js server on Amazon EC2 that is running socket.io for me. I'm working on a chrome extension that sends data between two clients. However, if I take the server offline, the clients don't attempt to reconnect automatically. I would like to implement this feature. When I do socket = io.connect("http://xxx.xxx.xxx.xxx:xxx") if it can't find the server at the specified IP address and port, how do I get it to fire an event that makes it go into a recursive loop until it can? Does something like this exist?
function connect() {
socket = io.connect("http://123.456.789.1011:1337");
socket.on('server_not_found', function() {
connect();
});
}
From the socket.io wiki it looks like there is a connect_failed event that you can listen to (https://github.com/LearnBoost/socket.io/wiki/Exposed-events). That event did not fire for me (see https://github.com/LearnBoost/socket.io-client/issues/375) but the error event will fire if the connection fails and you can check the connection status on the socket. You could try either and see what works better.
An example might look like:
function connect() {
var socket = io.connect("http://123.456.789.1011:1337"),
timer;
socket.on('error', function() {
// wait 5 seconds then try again
if (!socket.socket.connected) {
timer = window.setInterval(function() { connect() }, 5000);
}
});
socket.on('connect', function() {
// we've connected so clear the timer
window.clearInterval(timer);
});
}

Node.js: socket.io close client connection

How can I close the socket connection on the client side?
I am using:
socket.io 0.9
node.js 0.10.15
express 3.3.4
i.e.:
call localhost/test
-- server side
var test = io
.of('/test')
.on('connection', function (socket) {
console.log('open socket: ' + socket);
socket.on('disconnect', function () {
console.log('disconnected event');
//socket.manager.onClientDisconnect(socket.id); --> endless loop with this disconnect event on server side
//socket.disconnect(); --> same here
});
});
-- client side
var socket = io.connect('http://localhost:3000/test');
socket.on('disconnect', function () {
console.log('disconnect client event....');
});
socket.emit('getInitData', function (data) {
.. do something with data
});
If I load the test-page I need some values from the server (getInitData).
On the first page visit I get the data once, on a reload or second visit I get it twice and so on.
The connection on the server side is beeing closed automatically on page reload and if you leave the page.
But on the client side the connection is still open.
How can I close the connection on the client side or check if there is already a open connection?
UPDATE
I tried now the following: (client side)
window.onbeforeunload = function(e) {
socket.disconnect();
};
This triggers on the client side the disconnect event, but I still get the twice or tripple response.
Did you try:
socket.disconnect()
on client?
For socket.io version 1.4.5:
On server:
socket.on('end', function (){
socket.disconnect(0);
});
On client:
var socket = io();
socket.emit('end');
There is no such thing as connection on server side and/or browser side. There is only one connection. If one of the sides closes it, then it is closed (and you cannot push data to a connection that is closed obviously).
Now a browser closes the connection when you leave the page (it does not depend on the library/language/OS you are using on the sever-side). This is at least true for WebSockets (it might not be true for long polling because of keep-alive but hopefuly socket.io handles this correctly).
If a problem like this happens, then I'm pretty sure that there's a bug in your own code (on the server side). Possibly you are stacking some event handlers where you should not.
socket.disconnect()
Only reboots the connection firing disconnect event on client side. But gets connected again.
socket.close()
Disconnect the connection from client. The client will keep trying to connect.
socket.disconnect() is a synonym to socket.close() which disconnect the socket manually.
When you type in client side :
const socket = io('http://localhost');
this will open a connection with autoConnect: true , so the lib will try to reconnect again when you disconnect the socket from server, to disable the autoConnection:
const socket = io('http://localhost', {autoConnect: false});
socket.open();// synonym to socket.connect()
And if you want you can manually reconnect:
socket.on('disconnect', () => {
socket.open();
});
I'm trying to close users connection in version 1.0 and found this method:
socket.conn.close()
The difference between this method and disconnect() is that the client will keep trying to reconnect to the server.
try this to close the connection:
socket.close();
and if you want to open it again:
socket.connect();
Just try socket.disconnect(true) on the server side by emitting any event from the client side.

node.js server and client sideo code to connect

Im trying to set up a node.js server to send messages to the client, which will then display the messages using a jquery notification library, I'm using this notifcation library if anyone's interested: http://needim.github.com/noty/
At the minute I have a postgres database set up with a table which has a a trigger on it to write to a listener.
The trigger is as follows:
CREATE OR REPLACE FUNCTION new_noti() RETURNS trigger AS $$
DECLARE
BEGIN
PERFORM pg_notify('watchers', TG_TABLE_NAME || ',msg,' || NEW.msg );
RETURN new;
END;
$$ LANGUAGE plpgsql;
Then I have a node.js server as follows:
var pg = require ('pg');
var pgConString = "pg://aydin:password#localhost/test"
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, url = require('url')
app.listen(8080);
function handler (request, respsonse) {
var client = new pg.Client(pgConString);
client.connect();
client.query('LISTEN "watchers"');
client.on('notification', function(msg) {
console.log(msg.payload);
sendMessage(msg.payload);
});
}
function sendMessage(message) {
io.sockets.emit('notification', {'message': message});
}
Then I have some client code as follows:
<script type="text/javascript">
var socket = io.connect('http://localhost:8080');
socket.on('notification', function (data) {
console.log(data.message);
newNoty(data);
});
function newNoty(data) {
noty({
"text":data.message,
buttons: [{
type: 'button green',
text: 'Go to'
}],
"theme":"noty_theme_twitter",
"layout":"bottomRight",
"type":"information",
"animateOpen":{
"height":"toggle"
},
"animateClose":{
"height":"toggle"
},
"speed":500,
"timeout":7500,
"closeButton":true,
"closeOnSelfClick":true,
"closeOnSelfOver":false,
"modal":false,
});
}
</script>
This doesn't work, it seems the node.js never receives the postgres notifications, I think this is because I am using the function handler and I'm not actually firing any requests to it from the client code. I'm not sure how to do this and whether it is the correct way?
Is there a function on which can fire on connections and not requests?
And am I even doing it the right way round? should there be a server on the client side which node.js sends messages to? How does it know when a client is available? Any help or pointers to tutorials would be much appreciated. Thankyou.
You're not actually setting up your database connection until the client sends an HTTP request. It looks like that may never happen due to same-origin issues (your client code appears to be coming from somewhere other than the server you've shown).
In any case, you probably want to set up the connection in response to a "connection" event from io.sockets (i.e. move the stuff that's currently in the HTTP request handler there). That's how it "knows when a client is available". Or maybe you should be doing it as part of initialization. Your client-side code seems OK, but it's out of context so it's hard to tell whether it really fits your needs.

Categories

Resources