I have a Raspberry Pi and a computer, both connected to the same local network (both are connected to the same router, it's it's not the Pi who is acting as the router).How can I obtain the local IP address of the Raspberry Pi from a JavaScript script running in the computer (obs: by "client" I mean a JavaScript script running in the browser, not a node.js script)? I've thought of two approaches:
First one: To search for all local IPs, which would require the JavaScript client to know both his local IP and the subnet mask of the network, and would essentially try to get (via HTTP or whatever) some response from a specific port on the supposed Raspberry Pi IP address. However, I don't know how reliable that would be in terms of it taking too long to search the network and also of being able to obtain the local IP and subnet mask from the JavaScript client (from what I've read, the local IP is technically obtainable using a fake WebRTC request, even though it looks extremely unreliable; not so sure about the subnet)
Second one: To host a thin third-party server (on some other network) and make the Raspberry Pi server to send its local IP address to the server. When prompted by a request from the client, such third-party server would gracefully tell the Raspberry Pi IP address based on the public IP of the request (multiple requests could be handled from the third-party server, for various local networks).
I don't see why the second approach would not be viable. Is the first approach viable, however? And is there an easier way to solve the problem? Thank you.
I would like to set up the following: Alice and Bob should be connected on the internet through their cellular\independent main connections while communicating internally (LAN Router or Directly but not through the internet) in a web application. The environment is a web browser, such as Chrome.
For example, if a file has two parts 1 and 2, Alice downloads part 1 and share it upon completion to Bob. At the same time, Bob does the same for part 2 and shares it with Alice. The main point is that they collaboratively download the file without losing on their data plan by downloading it through their main connection.
Is there a way through client-side Javascript or a protocol that allows this behavior on the browser? I am looking at WebRTC but there's no way to control the path that the messages sent through the data channel takes from the browser.
Thank you!
Asaad
WebRTC does allow you to choose the path somewhat, you can exclude candidates you don't want to use when signaling.
When you are exchanging ICE candidates you can filter out any ones you don't want. By default if you don't include a STUN/TURN server in your iceServers list it will always be P2P in your LAN. During the gathering process the agent (browser) will only know about host candidates.
My two server machines are deployed behind a load balancer for high availability. When a user upload a file through browser, the file is stored on any of the server machine behind load balancer.
I want that file to send as an attachment through mail to the user using java but I don't know how to get the file path behind the load balancer?
I had faced this problem recently, and did some research about this. The best solution that I found was to keep a shared memory on some third machine, which would be accessible by both of your server machines. The file would be read and written from that machine only. The location of the file can be either kept in central logs, or central database.
Note that the way you are trying to do this requires the two machines to communicate with each other (network communication). By doing this, you would increase the request service time. Also, you'll get rid of the "high availability" requirement because one download request will invoke both the server machines (in worst case).
I'm using an arduino UNO and an Ethernet Shield to create a web server to response HTTP requests.
The requests are sent by ajax XMLHttpRequest.
It's working fine with static ip address.
But a want the arduindo to get a DHCP ip, so I can use it in any local network (with DHCP).
I want to discover the ip of the arduino connected on the local network.
So I can use it as url to send HTTP requests.
Is it possible to do that in javascript?
OK, thanks for answering my questions above. That helped layout the network structure and the problem you're trying to solve.
Summary of the problem
Two computers: 1 web server whose address is dynamic (DHCP) and 1 web client running AJAX and HTML. How can browser find DHCP server?
Options
This is a classic problem solved many different ways throughout the history of computer networks. I've suggested some options below.
Scan for the server via TCP.
Scan for the server via UDP (requires special browser library).
Run a DNS server.
Have Arduino signal its IP.
Modify your router.
Don't run DHCP - use a static IP.
tl;dr - Use Option 6 if you don't control your router, Option 5 if you do.
Option: Scan for the server
I'm assuming you know your browser machine's IP address (for example, 192.168.1.17). In this case, run through all of the address from 192.168.1.0 through 192.168.1.254 (not .255 and skip you browser machine's IP) testing for a connection to port 80. This will find every web server on your subnet, so be aware you will need a way to recognize your arduino responded to the web request in case some other web server is also listening on the network. It will also take some time to set up, test and wait for timeouts on most (252) of the addresses which don't have web servers. You will eventually find it.
I'm not a fan of this one, but it gets the job done. Warning: if you don't "own" the network, someone may be angry with you for scanning their machines. A company, school or other institution may have policies about not scanning networks.
Option: UDP from the browser
This one is great, but requires a browser plug-in and some fancy coding. UDP allows one to broadcast a message to your subnet (try ping 255.255.255.255 at a command line and watch the machines echo back their IPs). If the arduino is set to listen for UDP packets on a particular port, it can echo back to the sender of the UDP packet and let that user know it's present. This is how DNS, DHCP, ping and Apple's Bonjour work. Many IP based systems advertise services by responding to UDP requests. Clients need not know the address of the servers on the subnet, they discover them through broadcast messages on well-known UDP ports.
Unfortunately, this requires a browser modification because Javascript does not support UDP for security reasons. I understand this and agree with the security restriction. However, it has cut out a really nice feature of dynamic service discovery. If you're on Apple on the browser, you might be able to find a Bonjour emulator you can run on the Arduino and it might work ("arduino.local" might attach). This might be possible with Windows service discovery, too, if you're using a Windows client for your browser. I don't know what's available in Linux for service discovery.
I don't like any of these modifications for you. Browser, Arduino (Apple, Windows or Linux), just because it adds more moving parts and you're counting on the browser to "know" how to find the service.
Option: Run a DNS server
This isn't as bad as it sounds, but I'm not sure the Arduino could handle it. Find a very small DNS server written for the Arduino and have it respond to DNS requests. On the browser, look for a well-known machine name (e.g. "my-arduino.lan"). This essentially finesses the UDP problem above by making the Arduino the UDP server (handles DNS requests) and the browser already has name resolution s/w (like every machine on the planet).
I didn't search for Arduino DNS code, it might be too large for the Arduino and writing it may be a real PITA (pain in the butt).
Option: Arduino signals IP
In this model, you can attach a LCD to the arduino and have it present its IP address on the display. Alternatively, the arduino can send a message (via TCP) to a well known server on the network (internet or otherwise) reporting its IP address there. Your browser can query that server, pick up the IP address and then contact the Arduino directly. This introduces a 3rd machine and acts like your own hacked form of DDNS (look it up, if you're not familiar with it).
Option: Modify the router
If you own the router, you can modify the router to assign a specific IP address to the Arduino, even with DHCP. This is your best bet. Here, you control the network, can allow the Arduino to come up in DHCP while still fixing its IP address. You'll have to go through your router API (web or CLI) and figure out how to do it, it's a bit hard directing you as there are thousands of types of commercial and SOHO routers.
If you don't control the router...
Option: Use Static IP
This option is really your best. Give up on DHCP and just set the static IP of the arduino. Just make sure the IP address you pick doesn't conflict with any other servers on the subnet. That shouldn't be difficult.
I hope this helps.
The 2 best options I think:
1) When arduino starts, gets an IP address from DHCP, arduino should make a connection to a well know service provided by you. Also, each device should have an ID, defined by you during manufacturing, like mac address or part of mac address.
So, you can print on the box something like: 5c4e6f.my-well-know-host.com
Than, as I was suggesting, each time arduino starts, it tries to connect to that service passing parameters like:
POST www.my-well-know-host.com
ID: 5c4e6f
IP: 192.168.1.55
than, at that service, you update a DNS table to reflect this relation:
5c4e6f.my-well-know-host.com -> resolves to 192.168.1.55
obviously, from anywhere in the world the host 5c4e6f.my-well-know-host.com will resolve to 192.168.1.55, but you will only access it from you local network.
Tip: this is some kind of DDNS, but with network discovery purposes.
Tip2: there is an linux dns service called MyDNS, where the hosts are simply records inside a MySQL table, easy to maintain.
2) Network discovery
I don't know if arduino is capable to do it, but, the idea is to make arduino listen on a specific UDP port, like 4444, on any address.
So, you can build a windows app, and Android APP (I already made one android discovery for another purpose, not arduino), or, the best solution that I still researching on, is to make a custom page with some javascript code, that "looks" for devices listening on that specific port.
Works like that:
Device gets IP from DHCP
device starts a thread listening for broadcast packets on port 4444
a discovery app listen on another port, like 4445.
the discovery app announces itself using a broadcast packet to 4444 port (255.255.255.255:4444)
each device listening, reports back with its identification and IP to app port 4445.
This is a code to find the server ip:
<script type="text/javascript">
var ip = "<?php echo $_SERVER['SERVER_ADDR']; ?>";
alert(ip);
</script>
If you are using Johnny Five framework, then you can find APIs in that framework
A server that sends info (in this case temperature data, every second) through a socket connection which can be listened to.
The goal being to display temperature and dynamically update the value on a webpage, with javascript.
The server cannot be modified.
JavaScript can not open arbitrary TCP connections, as that would allow for all kinds of mayhem when combined with services who authenticate based on IP address, or not at all (and are only protected by firewalls). This includes Windows or NFS file shares, your average printer, your average LAN game, your average home router's web interface and lots of enterprise software.
You you cannot really prevent the browser from visiting a malicious site (since that includes visiting a trusted site with malicious ads). If these sites could effect arbitrary TCP connections, they could for example try out every IP address in the RFC 1918 private address ranges, or every IP address in the address range of the organization the client is coming from, and determine what devices you own. That alone would constitute a serious privacy breach, but imagine a malware site finding a printer and then printing out spam in your office once you visit it by accident.
What you can do is use a WebSocket server to translate native TCP to WebSockets. Most Websocket implementations will have such a server as a demonstration app, but you can also use a standalone proxy.
What you need to do is make the connection with PHP, or something else server side, and return the result via AJAX to your JavaScript.