standalone nodejs client connects to a self signed websocket (wss) - javascript

I have a node server (Meteor.js) that should communicate with another server using websockets.
As the communication is between servers that don't involve direct users, I've chosen to use a self signed certificate.
Where to add the certificate parameters from the node server (which is a client to the other server)
var soc = new WebSocket("wss://localhost:9000")
I've tested connecting in insecure mode with certification and it works fine.
var soc = new WebSocket("ws://localhost:9000")
Connecting from android application in secure mode after adding the certificates to the application works fine too.

I've found this solution, the part that allows the client to connect to a secure socket with a self-signed certificate is:
"rejectUnauthorized: false"
It accepts all certificates but it still keeps the connection encrypted.
'use strict';
var WebSocket = require('ws');
var soc = new WebSocket("wss://localhost:9000", {
protocolVersion: 8,
origin: 'https://localhost:9000',
rejectUnauthorized: false
});
console.log("launched");
soc.onopen = function (event) {
console.log("Sending message");
soc.send('{}');
};
soc.onmessage = function (event) {
console.log(event.data);
}
soc.on('error', function(event) {
console.log(event);
});

Related

Java Socket and JS WebSocket

So I am trying to make some sort of connection between my Java app and my Web app, I looked up websockets and they look really simple and easy to use :). And I created myself a Java Server, which uses the ServerSocket class.
Now the problem is I am able to connect to the server from the web, with the websocket, but I am unable to send data to the server... but when I tried to send data from a Java Client it worked fine... what might be the problem?
My Java/Scala (I followed this tutorial: https://www.tutorialspoint.com/java/java_networking.htm) server:
class Server(val port: Int) extends Thread {
private val serverSocket = new ServerSocket(port)
override def run(): Unit = {
try {
while(true) {
println("Waiting for client on port: " + serverSocket.getLocalPort)
val server = serverSocket.accept()
println(server.getRemoteSocketAddress)
val in = new DataInputStream(server.getInputStream())
println(in.readUTF())
val out = new DataOutputStream(server.getOutputStream())
out.writeUTF("Hello world!")
server.close()
}
} catch {
case s: SocketTimeoutException => println("Connection timed out!");
case e: Exception => e.printStackTrace()
}
}
}
My web js (I followed https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications ):
/**
* Created by samuelkodytek on 20/12/2016.
*/
var conn = new WebSocket('ws://127.0.0.1:8080');
conn.onopen = function(e) {
console.log("Connection established!");
conn.send("Hello!");
};
conn.onmessage = function(e) {
console.log(e.data);
};
A web socket server is not the same thing as a simple socket server. A server that offers web sockets must first offer HTTP or HTTPS services because the web socket is established when a web client sends an HTTP request with an Upgrade option and special fields for establishing the web socket. Even after the web socket is established, the connection still does not behave exactly like a regular socket. The Web Socket protocol uses frames to send or receive data. This is all considerably different from what you seem to expect.
One other thing that you should be aware of is that the browser will enforce the rule that the web socket must come from the same host as the page that is attempting to establish the web socket (the same protocol, address, and TCP port).

Why node.js requires an upgrade while trying to run an application on the localhost?

When I try to run my node.js application on a localhost server, it does not run and demands a required upgrade. I have tried to run the code but I get the following error:
server code
var WebSocketServer = require('ws').Server,
ws = new WebSocketServer({port: 80}),
CLIENTS=[];
**new connection etablished**
ws.on('connection', function(conn) {
CLIENTS.push(conn);
conn.on('message', function(message) {
console.log('received: %s', message);
sendAll(message);
});
console.log("new connection");
conn.send("NOUVEAU CLIENT CONNECTE");
**if you close connection**
conn.on('close', function() {
console.log("connection closed");
CLIENTS.splice(CLIENTS.indexOf(conn), 1);
});
});
**send messeages vers all clients**
function sendAll (message) {
for (var i=0; i<CLIENTS.length; i++) {
var j=i+1;
CLIENTS[i].send("Message pour le client "+j+": "+message);
}
}
client code
<p>
Result :<output name="" type="text" id="result" value"readonly"></output>
</p>
<input type="text" onchange="ws.send(this.value);">
</body>
<script>
var ws =new WebSocket('ws://localhost:80');
ws.onmessage=function(event){
document.getElementById("result").value=event.data;
}
</script>
Upgrade Required is a reference to the header that is sent when establishing a WebSocket connection between a client (i.e. the browser) and the server.
Like #Prinzhorn stated in his comment, you need a client application that connects to your WebSockets server, which could be a static html page. I recommend you reading this introduction to websockets to understand better how WebSockets work.
Do not open a client HTML file as a localhost URL but open the file directly.
After running your web-socket server,
localhost:[port]/client.html -> you will get the message "upgrade required".
file:///[folder]/client.html -> you can see your HTML file.
because you don't have any web-server with a web-socket or you did not configure your web server for your web-socket. So, you should use your file system.
The easiest way is to use right click on the client file and open it with your favorite browser.
You need to combine your WebSocket based server and static html generator Express.
For example
var express = require('express')
var expressWs = require('express-ws')
var app = express()
expressWs(app)
app.ws('/echo', (ws, req) => {
ws.on('connection', function (connection) {
//...
})
ws.on('close', function () {
//...
})
})
app.use(express.static('public'))
app.listen(3000, function () {
console.log('Example app listening on port 3000!')
})
In client code
var ws = new WebSocket('ws://localhost:3000/echo');
ws.onmessage=function(event){
document.getElementById("result").value=event.data;
}
The issue is that your web socket server is running on port 80, so when you open the html template using your browser, you are actually opening the web socket server. This is because web pages opening in the browser default to using port 80.
To fix this set your web socket server's port to something else like 3000.
ws = new WebSocketServer({port: 3000})
Then when you open the page in the browser it will open the actual html page instead of the web socket server.

websockets - ws with node

I'm trying to push messages from server to client using ws module in node.js application.
Please find below the code in app.js.
var server = app.listen(port);
var WebSocketServer = require('ws').Server
var wss = new WebSocketServer({ server: server});
wss.on('connection', function (ws) {
console.log('connected');
});
ws.on('message', function (data, flags) {
});
});
code in the client side js file.
window.WebSocket = window.WebSocket || window.MozWebSocket;
var host = window.document.location.host.replace(/:.*/, '');
var port = window.document.location.port;
var socketConnection = new WebSocket('ws://'+ host+':'+ port);
socketConnection.onerror = function (error) {
// TODO : report error here..
};
socketConnection.onmessage = function (message) {
var obj = JSON.parse(message.data)
};
The problem is when i'm running the node application locally.i.e http://localhost:port and when I try to handshake with ws connection through "ws://localhost:port\". The handshake happens and i am able to send and receive messages.
But when i access the same application using the ip of my machine i.e as http://10.xx.yy.zz:port. Im able to open the application and do evrything but the handshake with websockets time out. The same happens when the app is running in another machine and i try to connect to it from my machines browser.The handshake doesnot happen and it times out.
I have tried the same with demos provided out of box by ws module. The same happens. Am I missing something when creating the websocket server?

javascript: print websocket client IP

node.js WebSocket example code snippet
I have a simple node.js application using express. Now everytime a client connects to the node server I see the string 'new client connected' but I would like to know which IP the new client had.
var WebSocketServer = require('ws').Server;
var connIds = [];
var server = require('http').createServer(app).listen(80);
// set up the websocket server
var wss = new WebSocketServer( { server: server } );
wss.clientConnections = {};
// websocket server eventlisteners and callbacks
wss.on('connection', function (connection) {
console.log('wss.on.connection - new client connected');
...
See the code at:
https://github.com/qknight/relais.js/blob/master/relais.js/server.js#L159
question
The object connection has properties but I don't understand how to query them or what they are. All I want is to print the client IP and maybe, if existent, other similar properties as well.
How do I do that?
Remote IP is a property of the pre-upgrade connection:
var wss = new WebSocketServer({port: 9876});
wss.on('connection', function(ws) {
console.log(ws.upgradeReq.connection.remoteAddress);
});
i don't recall how i found it, but i know it took me a while; i wish the docs were as good as the code...
UPDATE:
WS has moved some things around, so here's an updated example of how to get the original HTTP info in current code. Note the 2nd argument to the connection event handler:
wss.on('connection', function conn(ws, req) {
var ip = req.connection.remoteAddress;
console.info(ip);
});

netty secure websockets using http.. possible?

I have configured my websocket connection following the example:
https://github.com/netty/netty/tree/3/src/main/java/org/jboss/netty/example/http/websocketx/sslserver
This all works, i have the browser connecting to a secured websocket using https address.
$(document).ready(function () {
var location = "wss://localhost:9999/websocket"
ws = new WebSocket(location);
ws.onopen = function(event) {
}
ws.onclose = function(event) {
}
ws.onmessage = function(event) {
}
});
I want to connect to this page that makes the websocket connection using http?... is that possible ?... I have tried this, and it doesn't seem to work.. so im not sure...
I have read that it is possible to create a WSS connection when regardless of going to the page using http or https?.. is this correct?

Categories