Listing is a Django application, so theoretically I could just go through the list of IPs, ping and add status to the list that gets passed to Django template. But nice it is not. It might take ages to query the whole list, and even if I spend time implementing multithreaded ping and ping them all concurrently it still going to take at leas couple of seconds to complete.
So obvious choice is to delay the ping action. I will serve the page with all IPs and other bits and pieces and then let my JavaScript to do the AJAX magic.
So, how do I do that?
Well, first I need a view that checks if the given IP responds to a ping and displays the result. To keep things simple, I’m going to return a string, which will be displayed on the list page:
def ping(request, address=None): if responding_to_ping(address): msg = "Ping OK" else: msg = "No response" return HttpResponse(msg)
I then need to add URL pattern, so I can call the view:
url(r'^ping/(?P<address>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/$', views.ping),
Good, so now I can navigate to http://
Right, now let’s add some JavaScript magic that’ll query the server and update my web page with details.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <script type="text/javascript" src="/static/js/jquery-1.3.2.min.js"></script> <script type="text/javascript"> $(document).ready(function(){ $(".address").each(function () { var curId = $(this).attr('id'); updateStatus(curId); }); }); function updateStatus(attrId) { address = attrId.replace('ip_', ''); address = address.replace(/_/g, '.'); $.ajax({ url: '/ping/' + address, success: function(response) { $('#' + attrId).html(response); } }); } </script> |
So, what exactly is happening here?
- Line 3: This waits for a document too load and call the callback function when ready to proceed, calback function defined in the lines below
- Lines 4-6:Goes through each element of the HTML document (my web page) that are of class “address”, extracts the element’s ‘id’ attribute, and calls ‘updateStatus’ function passing the ‘id’ to it. So all elements that are going to be updated should look like: <span class=”address” id=”ip_address” />
- Lines 11-12: All id’s are going to be in the following format: ip_1_2_3_4, so before I pass this to the URL, I need to strip the ip_ bit, and replace underscores with dots.
- Lines 13-17: This is where I perform AJAX call to the URL. The ‘success’ bit is a call to the function that gets executed when the result is successfully retrieved. This function is pretty simple, it just replaces the contents of the tag with whatever it receives from the server
And this is it, all that is left to do is list all IPs that need checking. Below is the raw HTML, but I trust you can be creative in writing a decent Django template to generate the page.
<ul>
<li>192.168.0.1 [Status: <span class="address" id="ip_192_168_0_1">Unknown</span> ]</li>
<li>192.168.0.2 [Status: <span class="address" id="ip_192_168_0_2">Unknown</span> ]</li>
<li>192.168.0.3 [Status: <span class="address" id="ip_192_168_0_3">Unknown</span> ]</li>
...
</ul>Related posts:
Your approach is spot on. You may run into some issues after a while if your list of IP addresses becomes long. You may want to use the excellent jQuery Timers plugin to manage the ping operations via jQuery/AJAX. It’s the closest thing to threading in JavaScript.
Nizam, cheers for pointing out this plugin, I’ll have a read a bout it.
You mentioned that long lists might cause issues, is that because all requests will be processed in parallel? In which case using this plugin I could process them in streams, ie 10-20 at a time only, and then next batch, or something along those lines?
Thanks for your post. I am new at development and this will be a big help.
Just landed on this place via Google seek. I love it. This situation switch my percept and I am fixing the RSS feeds. Cheers.
df
have a test