Javascript client: Websocket not working? - javascript

I have a PHP websocket (Ratchet 13) and it works fine. I can connect to this ws via C# without any problem.
Now, i would like to connect to my websocket but with javascript, and in client side.
On my website, i would like the client to be connected to my websocket, and can send/received real-time data from the server.
Actually the connection success, but events are never called.
EDIT: After few mins the page is loaded, i have this in the console:
"WebSocket connection to 'ws://x:8080/' failed: WebSocket opening handshake timed out"
I have tried a lot of methods.
document.getElementById("value_ws").innerHTML = "coning";
//just some cheks 1
var ws = new WebSocket("ws://localhost:8080");
//here i replace localhost by my IP otherwise it don't connect
ws.onopen = function(e) {
console.log("open");
};
ws.addEventListener('open', function (event) {
ws.send('Hello Server!');
});
//both of theses events are never called
//i successfully receive the connection on my server ws console
//but when i send data, the event is never called
document.getElementById("value_ws").innerHTML = "coned";
//just some cheks 2
If you have some tips you can give me, i take!
Best regards

SOLVED:
problem was coming from my server that wasn't answering the handshake.
<?php
use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
use MyApp\Chat;
require dirname(__DIR__) . '/vendor/autoload.php';
$server = IoServer::factory(
new HttpServer(
new WsServer(
new Chat()
)
),
8080
);
$server->run();

Some browsers won't let you connect to unsecured websockets. You would need to test with SSL/TLS enabled and "wss://localhost:8080" as your connection.

Related

NodeJS Websocket client stay in pending mode

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);
});

Is it possible to create a "fake" socket connection to a nodejs server that is secured through SSL?

I'm using socket.io-client to create a socket connection to my locally-running server. See my code below:
// Working example of connecting to a local server that is not SSL protected
var io = require('socket.io-client')
var socket = io.connect('http://localhost:3000', {reconnect: true});
socket.on('connect', function(){ console.log("inside 'connect'") } );
socket.on('connection', function(){ console.log("inside 'connection'") } );
socket.on('event', function(data){ console.log("inside 'event'") } );
socket.on('disconnect', function(){ console.log("inside 'disconnect'") } );
var payload = {email: 'fake#gmail.com', password: 'tester'};
var tokens = {browserId: 'b965e554-b4d2-5d53-fd69-b2ca5483537a'};
socket.emit("publish", {logic:"user", method:"signIn"}, payload, tokens, function(err, creds) {
console.log("inside the socket client emit callback. err: " + err);
console.log("creds: " + creds);
});
Now for my problem. As I stated in the comment at the top of that code, I can connect to my local nodejs server and get the response I expect when I turn off SSL encryption on my server. As soon as I turn SSL on, I stop getting any response at all from the code above. I don't see any message in my server logs or from the command line, where I'm running the code above with node.
My goal is to be able to run the code above, with SSL turned on in my server, and get the same response that I get when SSL is turned off. I've tried a bunch of variations on the code I included above, such as:
connecting to "https://localhost:3000"
connecting to "//localhost:3000"
connecting to "https://localhost:3443" (this is the port I have to connect to when I have the nodejs server running with SSL)
changing {reconnect:true} to {reconnect:true,secure:true}
I'm truly stumped, and I've been doing a bunch of research on the web and on my node server. It's my company's code and I didn't originally implement the SSL components, so I've spent a few hours looking at our code and trying to understand how adding SSL changes everything. I'm also a student and have about 2 years of experience behind me, so I'm good but I'm no expert. Have I said anything above that indicates if my task is impossible to achieve, or if maybe I have just overlooked something? Any leads on things to check out would be appreciated :)

What is the best way to map websockets connection to users in the database?

I am looking to map websockets connection with users in the database and have something like this at the moment:
function connectToNotifServer(){
var conn = new WebSocket('ws://localhost:8080');
conn.onopen = function(e) {
alert("Connection established!");
conn.send(JSON.stringify({user_id: sessionStorage.getItem("user_id")}));
};
conn.onmessage = function(e) {
alert(e.data);
};
conn.onclose = function(e) {
alert("Connection closed!");
};
return conn;
}
I then have a PHP websockets server, that keeps a mapping of a connection to user_id.
However, I think there is a security flaw, as a user could simply inject any value he want in the user_id and impersonate another user. Is there a better way to keep this mapping, but without sending the user_id or sending it in another way?
Thanks
Anything you send which is 'built in' to your javascript could, at least, be copied and duplicated. The only way to verify a user's credentials to the server side websocket would be for the PCP websocket server to require something like 'username/password' - which it then checks server-side and persists for that websocket only.
i.e. you would have to ask the user to input this info.

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.

Socket.io takes a long time before triggering the disconnect event

I'm doing an HTML5 Game using node.js and socket.io
I decided to host it on Heroku.
Heroku isn't allowing the use of WebSockets, so I have to setup xhr-polling instead. (Socket-io on Heroku)
io.configure( function() {
io.set( "transports", ["xhr-polling"] );
io.set( "polling duration", 10 );
} );
Before, I was using web-sockets only
io.set( "transports", ["websocket"] );
Now, when a client disconnect (close his window or refresh his page) the event "disconnect" isn't trigger immediatly on the server (it looks like it's waiting for the client heartbeat to time out).
client.on( "disconnect", onClientDisconnect );
If the client reloads, I get multiple connection events before disconnect is fired.
My problem is here.
Do you have any ideas, why xhr-polling doesn't fire the disconnect event ?
Is this a bad configuration of socket.io ?
Thanks.
It says here that you can configure the heartbeat. To properly configure it, you must adjust the heartbeat both on the server and the client side (which is given here).
Try lowering the heartbeat. It may solve your problem.
On other note, appfog seems to support websockets.
Just configure session auth and you can always know what client has connected. E.g.
io.set('authorization', function(handshakeData, ack) {
var cookies = require(...);
var signedCookies = parseCookies(cookies, secret);
sessionStore.get(signedCookies['connect.sid'], function(err, sessionData) {
handshakeData.session = sessionData || {};
handshakeData.sid = signedCookies['connect.sid'] || null;
ack(err, err ? false : true);
});
});

Categories

Resources