java - Counting current users viewing a page -



java - Counting current users viewing a page -

i working on counting number of viewing user on page. basically, when user view url localhost:8080/itemdetail.do?itemid=1, page showing how many users viewing on page @ same time.

solution approach

when user viewing particular page, page go on send ajax request every 1 sec server, server utilize map<string, map<string, integer>> (both utilize concurrenthashmap initialization) contain itemid (to know page viewed) , ip , timeout count (in inner map). every time getting request, counting increment 1. there thread fired during request process decrease timeout counting every 2 seconds. if in end, timeout counting equal 0, app consider user stopped viewing page, thread remove entry , number of user decreased 1. little problem approach since timeout number increasing faster decreasing, if user open page long plenty , close page, app take sometime know that user left page, because timeout number @ moment quite big

implementation

// controller @requestmapping(value = appconstants.action_number_viewing, method = get) @responsebody public int useritemviewing(httpservletrequest request, @requestparam(value = "itemid") string itemid) { seek { homecoming eventservice.countuseronline(request, itemid); } grab (caserviceexception e) { e.printstacktrace(); log.error("========== error when counting number of online user ==========" + e.getmessage()); } homecoming 0; } // service private static map<string, map<string, integer>> numberofcurrentviews; private thread countdownonlinethread; class onlinecountingdownrunnable implements runnable { private list<string> timeoutlist = new arraylist<string>(); private void cleantimeoutips() { (string itemid : numberofcurrentviews.keyset()) { map<string, integer> currentips = numberofcurrentviews.get(itemid); for(string ip : timeoutlist){ currentips.remove(ip); } } } @override public void run() { seek { (string itemid : numberofcurrentviews.keyset()) { map<string, integer> currentips = numberofcurrentviews.get(itemid); for(string ip : currentips.keyset()){ integer timeout = new integer(currentips.get(ip).intvalue() - 1); if (timeout == 0) { timeoutlist.add(ip); } currentips.put(ip, timeout); } } cleantimeoutips(); // counting downwards time must double increasing time thread.sleep(2000); } grab (interruptedexception e) { e.printstacktrace(); log.error("---------------- thread error in counting downwards online user: " + e.getmessage()); } } } public int countuseronline(httpservletrequest request, string itemid) throws caserviceexception { // create count downwards timer observe if user not view page anymore string ip = request.getremoteaddr(); // init counting downwards online user map if (numberofcurrentviews == null) { numberofcurrentviews = new concurrenthashmap<string, map<string, integer>>(); } // start thread check user online if (countdownonlinethread == null) { countdownonlinethread = new thread(new onlinecountingdownrunnable()); countdownonlinethread.start(); } log.debug("---------------- requested ip: " + ip); if (ip == null || ip.isempty()) { throw new caserviceexception("======= cannot observe ip of client ======="); } if (numberofcurrentviews.get(itemid) != null) { map<string, integer> userview = numberofcurrentviews.get(itemid); if (userview.get(ip) != null) { userview.put(ip, userview.get(ip).intvalue() + 1); } else { userview.put(ip, 1); } numberofcurrentviews.put(itemid, userview); } else { map<string, integer> ips = new concurrenthashmap<string, integer>(); ips.put(ip, 1); numberofcurrentviews.put(itemid, ips); } log.debug(string.format( "============= %s seeing there %s users viewing item %s =============", ip, numberofcurrentviews.get(itemid).size(), itemid )); homecoming numberofcurrentviews.get(itemid).size(); }

problems

i have no thought how test functionality since requires multiple ip addresses view page. have tried set jmeter , set ip spoofing link not successful, made little mock test view log

@test public void testcountuseronline() throws exception { list<httpservletrequest> requests = new arraylist<httpservletrequest>(); (int = 0; < 10; ++) { httpservletrequest request = mockito.mock(httpservletrequest.class); mockito.when(request.getremoteaddr()).thenreturn(string.format("192.168.1.%s", i)); requests.add(request); } list<thread> threads = new arraylist<thread>(); (int = 0; < 10; ++) { thread thread = new thread(new requestrunnable(requests.get(i))); threads.add(thread); thread.start(); } (thread thread : threads) { thread.join(); } } class requestrunnable implements runnable { private httpservletrequest request; public requestrunnable(httpservletrequest request) { this.request = request; } public void run() { seek { int = 0; while (i < 10) { eventservice.countuseronline(request, "1"); i++; system.out.println(i); thread.sleep(1000); } } grab (caserviceexception e) { e.printstacktrace(); } grab (interruptedexception e) { e.printstacktrace(); } } }

but again, not confident implementation

also, normal way human using count number of viewing users on page? want create sure don't miss in case there shortcut part. using spring mvc 3.x. need back upwards ie 9 :(((, web socket cannot used extensively

have tried apache benchmarking tool ?

http://httpd.apache.org/docs/2.2/programs/ab.html

java spring-mvc mockito distributed-computing

Comments

Popular posts from this blog

formatting - SAS SQL Datepart function returning odd values -

c++ - Apple Mach-O Linker Error(Duplicate Symbols For Architecture armv7) -

php - Yii 2: Unable to find a class into the extension 'yii2-admin' -