TL;DR
In Javascript, how do you to find the IP of all servers running a specified program on a specified port in the LAN?
Background
I'm writing a server in node.js that is supposed to connect users browsers as controllers to a common device on which a game is running. The browsers are running a web app based on html and Javascript. The connection is based on socket.io.
I'd like for the web app to be able to find all available instances of this server in the LAN in order to create a server list for the user to choose from.
Is there a way to make the server discoverable by the web app on the local network in Javascript, and in that case: how?
Ideas
Have the server broadcast its IP to all devices on the LAN and have the web app listen for these messages (No idea how to do this without node on the client)
Connect to every IP on the network and see if the connection is successful. (Does not seem feasible)
Scan every IP on the network and connect only to those where the port is open. (Once again, no idea how to do this without node on the client and does not seeem feasible either.)
EDIT
The server is supposed to be portable and work independently, without any central system backing it up or providing matchmaking for clients. It is a LAN only server and should work even without internet access.
There is no way for you do this. Sorry. Since there is no exposure to UDP on client-side JavaScript, broadcasting is out of question. Any attempt on massive scanning will quickly raise flags on network monitoring software. You have to use a known address.
Related
For a mostly offline browser game I'm researching the possibility to run a WebRTC signalling server from a browser.
I can imagine that security-wise it's a big no-no to open a port and serve connections from a browser (or service worker), but I cannot* find any information on this.
Q. Can Chrome, Firefox (or perhaps any other major browser) open a network port and serve connections using javascript? Or is this fundamentally disallowed by browser design?
*) For sake of completeness, I did find one option (maybe), but it's overly complex, and therefore isn't very appealing. There is a javascript package called filerjs, which allows for a posix-like filesytem in the browser, I think using indexedb, that would allow for a nodejs installation in the browser. I did not further investigate it, so no idea if it actually works, and if a connection could be served this way.
I don't think that you can run a signaling server in the browser. But you say "mostly offline", does that mean that the peers are connected to the internet, but playing from the same LAN? Or are they completely offline? Here are a few ideas:
Signaling server on the web
Even if the signaling server is running on the web, chances are that WebRTC will connect directly through the LAN (to be tested, and it may depend on how the browser selects the ICE candidates).
Manual signaling
Now, the signaling server is only there to exchange SDP messages. So you could theoretically copy-paste the offer and answer (or copy it manually, or scan it with a QR code). It may not be practical, but for instance you could try hardcoding the SDP offer/answer. The two players would need to exchange information somehow, though:
The ICE candidates (those are IPs) that you would need to create the SDP message
The SDP type (one has to be the offer, the other has to be the answer)
I never tried it, but maybe your UI could tell the player "Please share the following IPs to the other player, and enter their IPs below. Also select if you are the offerer or the answerer". But you see that it seems a bit convoluted...
Signaling server in the LAN
If the peers are completely offline and the manual signaling is too convoluted, my next idea would be to run the signaling server in the LAN, and have the peers connect to it. You could even make it such that your game first tries to contact your signaling server on the Internet, and if it fails (because it is offline), it could fallback and try to contact the one in the LAN (maybe it would need to ask the user for the IP of the signaling server, then).
I have a desktop application and I am using the Process.Start property in this application. Can I somehow send a request to this program over the web?
Note: I cannot install iis or similar things on the device as it is a company computer.
Typically, the desktop application would act as a client here, and contact the server (possibly the same server that runs the web app, possibly a slightly different server intended just for API access). It is possible for a browser application to talk to a desktop application, by having the desktop application install itself as a custom protocol handler - but this may require more permission than you are allowed on the desktop machine, and it is relatively complex. Having the desktop app talk to a server, and the browser app talk to a server, but not directly to each-other: is a simpler setup.
If you mean to do this without any kind of browser session on the same machine, then:
either the desktop app needs to be running as a client, connecting to a server, and listening for messages, or:
the app needs to be a server, and open an inbound TCP/UDP port, to listen for connections/messages
The second option presents much more security issues; in a lot of corporate scenarios, this could be disallowed and blocked by corporate firewalls, or could even have the network security folks arrive at your desk with a cardboard box for your things.
You will need to setup your server somewhere in the internet or inside company LAN.
Desktop app should connect to this server and keep connected, waiting for a data. Or you can check for a new data by a timer, if your scenario allows some delays.
When you need to make a request, you send data to your server (may be including client id or something similar to identify the exact instance of the desktop app).
The server forwards data to the desktop app and then forwards the app's response back to you.
Note: you will not able to connect directly to the desktop client without intermediate server, as most likely the company computer does not have "white" ip and is located behind the company's NAT.
Situation
We have:
A JSF web application that runs on an Application Server.
A Java Server Socket application for smart card access that runs on the client computer.
The web application needs to read a smart card in a smart card reader on the client computer.
For this the web application makes a connection to the Server Socket application on the client computer with the IP address of the client computer.
This IP address is determined through ServletRequest object of our web application call.
Problem
When this setup runs in a RD environment (eg Citrix), we receive the server IP address instead of the client computer IP address.
Question
How can we retrieve the client IP address?
Perhaps by using WebSockets?
Comment
I am not sure if these are correct, but I have looked around and some possible solutions found are:
using a Virtual IP Policy (I understand that this would make the localhost call revert to the correct IP address?)
Adding a X-Forwarded-For header to the request
These would require modification/configuration of the RD environment and we don't manage this level.
Of course, if there is no other way, I can try to request this.
You should try X-Forwarded-For. Worked for us. Somehow different scenario but it worked for us.
I am working on a way to force the game Alien vs. Predator 2 to connect to specific IP address. The reason is, that quite often the server is reachable, but the UDP broadcast the game sends to discover it do not reach the server.
On localhost, this kind of discovery always works. So what I thought I could do is a simple console application that will listen on UDP broadcast from the game and reply. The reply needs to look like it came from the real server's IP, not localhost.
I figure that with no ISP/firewalls involved, this should be much simpler.
I read Node.JS UDP dgrams documentation. It says how to specify target address and port for a message, but it seems to rely on OS' behavior for filling up the source IP and port.
Is there another way?
You can try adding a line to your operating system host file:
127.0.0.1 **the_original_game_server_ip**
This will redirect all traffic to localhost instead of the game server.
Now just create a console application that listens to the game server port.
I have a web app in javascript that connects to a socket using socket.io and a Chrome Extension which connects in the same way and to the same server.
Everything works fine in most computers and internet connections, but one of my customer's computer is failing to have the Chrome Extension connected (the web app connects successfully).
By inspecting the extension's console for background.js (the script within the extension creating the socket connection) I see that it is not trying to connect to the right URL (my socket server) but to an unknown URL which seems to be a proxy: https://gateway.zscloud.net/auT?origurl=http%3A%2F%2Fmy_socket_server_domain...
Since this is happening only in that specific computer (from the 10 or so that I have tried with so far) using different internet connections (corporate network, guests network, mobile hotspot) and since other computers in those same networks DID succeed in connecting, I assume something installed or configured in the problematic computer is catching the connection request before it happens and tries to redirect it through a proxy.
Again, this happens only in the context of the Chrome Extension. The very same computer using the same internet connection DOES succeed in connecting from a web page in the same browser (Google Chrome).
Does anybody know what the problem could be? The client is not aware of having a security software (firewall, antivirus, etc...) that could be causing this, but it's a computer managed by his company so an admin could have done that for him. If that was the case, however, shouldn't the connection from the webpage be captured too? Is there anything specific to socket connections in Chrome Extensions that differ from regular web apps?
Thanks!
WebSocket connections differ from normal HTTP requests; they require a protocol upgrade after establishing that (some!) proxies may be unable to support.
I was at some point behind one such (transparent) proxy at work; however, it does not attempt to intercept HTTPS, which means I could use wss: WebSockets but not ws: WebSockets.
..which you should be using, anyway! With Let's Encrypt on the market, the barrier of entry for HTTPS is very low. If any sensitive data at all is sent through that connection, it's in your best interest.
For the record, that particular proxy is part of ZScaler which is a security solution. Sadly, it includes HTTPS MITM, so the above is unlikely to solve the problem (but should be implemented anyway!). It's set up as an OS-level proxy - if that setting is possible to change, or override with Chrome's proxy settings, that would fix it. However, that's going to piss off network security!
If you can't do that, then your client is a SOL and should complain up the chain about the security solution breaking legitimate applications.
Edit: I looked around and found this, which seems to claim that using SSL (that is, wss:) is enough. But that's from 2012 - perhaps before ZScaler was able to MITM all HTTPS traffic.
It should be possible to test whether wss: switch will work using https://www.websocket.org/echo.html - if it can connect then everything will work over wss: