Servlet i wielowątkowość

0

Chce zrobić automatyczne wylogowywanie kont w servlecie. I teraz nie wiem jak to za bardzo zrobic, poniewaz Servlet sam w sobie jest wątkiem i nie wiem za bardzo jeszcze w ktorym momencie zostaje dokladnie powolany a kiedy zniszczony.
Moja koncepcja była taka, aby wysyłać co jakis czas sygnał pochodzacy od klienta na servlet, a wątek uruchomiony po stronie serwera sprawdzal jak dlugo klient jest zalogowany. Napisałem kiedyś serwer w RMI, ale tu chyba jest inaczej z wielowątkowością.

Co doradzicie?

0

Servlet nie jest watkiem. Servlet jest zawsze 1 (no sa wyjatki ninechlubne jak implementowanie interfejsu SingleThreadModel, ale olejmy to). To oznacza ze servlet nie powinien przechowywac stanu, stan powinien sie znajdowac w 3 miejsach - HttpServletRequest, HttpSession, ServletContext (globalny).
Jak chcesz zrobic automatyczne wylogowanie uzytkownika, to moze napisz sobie HttpSessionListener, ktora w metodzie sessionDestroyed() wyloguje uzytkownika? Dlugosc sesji da sie konfigurowac w web.xml, tomcat ma domyslnie 30 min. Oznacza to, ze jesli uzytkownik by nie byl aktywny przez 30 min, to sesja sie zakonczy, i automatycznie by wykonany byl twoj kod wylogowania uzytkownika.
Calkiem mozliwe ze nie do konca zrozumialem o co Tobie chodzi, i ze np chcesz uzytkownika zawsze wylogowac np po 30 min, bez wzgledu na to czy byl aktywny czy nie. Jesli tak to odpisz a ktos na pewno odpowie.

0

Udało mi się uruchomić wątek po pewnych manewrach z synchronizacją i widzę że wątek działa cały czas, nawet gdy nie ma żądania od klienta. Zatem powinno mi się udać zrobić to co chcę po mojej myśli. Mam zamiar wysyłać sygnał od klienta co pewien czas by aktualizował swój czas zalogowania, a servlet w wątku który cały czas chodzi będzie co ileś sekund dokonywał sprzątania tzn. usuwał te osoby które przez jakiś dłuższy czas nie zaktualizowały swojejego czasu zalogowania.

0

Jak chcesz zabijać sesję to należy użyć odpowiedniego wpisu w pliku web.xml (session-timeout). Po upłynięciu czasu nastąpi zniszczenie sesji i tym samym kolejne żądanie od klienta będzie traktowane jak nowe przez mechanizm zarządzania sesją.

@cfaniak, to co zrobiłeś jest uruchomieniem wątku z servletu i nie będzie działało, a tylko będzie pożerać zasoby.

0

Tak w ogole nie wiem czy Ty wiesz, ze ten watek bedzie otrzymywal sygnaly od kazdego klienta, nie tylko jednego. Jesli servlet startuje watek, to ten watek bedzie wspolny dla kazdego klienta, bo jak napisalem wczesniej, jest tylko jedna instancja servlata na 1 wpis w web.xml (za wyjatkiem wyjatku ;d o ktorym napisalem). Cos mi tu smierdzi tym ze nie masz pojecia o servletach a chcesz pisac nie wiadomo co. Aha, servlet tworzony jest albo podczas deploya aplikacji webowej (np podczas startu tomcata jesli aplikacja jest w katalogy webapps) lub gdy pierwszy request zostanie do niego skierowany. Zalezy do glownie od elementru load-on-startup w web.xml. Niszczony jest arbitralnie - specyfikacja mowi ze 1 servlet moze obslugiwac 1 request, i byc niszczony, moze byc ten sam przez lata, a moze byc niszczony gdy potrzebne sa zasoby i pozniej znowu tworzona nowa instancja gdy potrzeba. Takze, calkowiecie bledne jest Twoje rozumowanie chyba, a jesl nie to za malo informacji podales co do tego co i jak chcesz robic.

0

No nie wiem, może zajasno się nie wyraziłem. Klientem ma być program w J2ME, a połączenia nie będą często otwierane. Zrobilem tak, ze funkcja wywoływana z klienta mobilnego typu loguj gdy dane są poprawne dodaje do info o tej osobie do listy na servlecie. Gdy zbyt dlugo nie uzyskamy zadnej odp. od klienta, czyli nie wyśle on kodu aktualizującego czas zalogowania ( bedzie polegalo na otwarciu i zamknieciu połączenia) to servlet usunie tę osobę z listy zalogowanych.

@eciepecie w tym co napisałeś jest nieco niejasności.
W sieci znalazłem coś takiego o wielowątkowości w servletach:

Wzmianka o wielowątkowości

Serwlety wykonują się w środowisku wielowątkowym, więc może się zdarzyć, że wiele kopii serwletu będzie działać naraz. A może być tak, że będzie jedna instancja serwletu, ale wiele wątków wykonujących metodę service. Jeżeli w serwlecie jest odwołanie do zasobu, który wymaga wyłączności to:
trzeba zapewnić wykluczanie ręcznie, np. używając zmiennych/metod synchronized
zadeklarować, że serwlet implementuje interfejs SingleThreadModel, wtedy serwer uruchomi jednocześnie tylko jedną instancję metody service, np. public class ReceiptServlet extends HttpServlet implements SingleThreadModel. Ten interfejs nie zawiera żadnych metod, jest tylko znacznikiem dla kontenera.

Źródło: http://stencel.mimuw.edu.pl/abwi/20020108.a.servlet/

I z tego co napisałeś to właśnie to chcę osiągnąć. Ale thx za odp. ;-)

0

W porzadku. Ale po co chcesz to pisac sam? I Koziolek i ja wczesniej napisalismy ci jak to robic w sposob standardowy (sessio-timeout i ewentualnie session listener jesli chcesz robic cos konkretnego na wylogowaniu). Masz gwarancje ze to zadziala zawsze i wszedzie tak samo, gwarantuje to specyfikacja. Natomiast wlasne zabawy z watkami to nie jest dobra sprawa. Co zrobisz jak servlet zostanie usuniety, a pozniej utworzona nowa instancja? Tworzony jest nowy watek, i chodza 2 na raz? I masz juz pierwszego potencjalnego resource-leaka na dzien dobry. Teoretycznie mozesz w metodzie finalize servletu konczyc watek, ale specyfikacja javy nie gwarantuje ci kiedy ten finalize zostanie wywolany, moze nigdy, albo po roku, jedyne co wiesz to to ze zostanie wywolane tylko raz.

0

Poszukam w sieci o tym co piszecie. Po prostu nie wiedziałem że takie mechanizmy istnieją.

0

Nie powinno sie uzywac SingleThreadModel, jest @Deprecated od jakiegos czasu (chyba zpesyfikacji servlet 2.4). Gdy go nie implementujesz, zawsze bedzie jeden servlet obslugujacy requesty.Zapomnij o SingleThreadModel.

0

Zapomnij tez o tym tekscie, ma bledy. Np, nigdy nie slyszalem o zmiennych synchronized, moga takie byc tylko metody lub bloki kodu.

0

No moze nie jest to za dobrze napisane ale -> "...używając zmiennych/metod synchronized" wiadomo co autor miał na myśli. Ja bym sie nie czepial tego.

0

Łotefer.

0

Przecież ten tekst ma już ponad 7 lat. Nic dziwnego, że jest nieaktualny.

Serwlety są wielowątkowe i tyle.

0

Pomocy Panowie

Dołączam swoje pytanie do tego wątku.

Mam trywialną aplikację testową: formularz i jeden servlet. Domyślny get zawiera:

protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	response.setContentType("text/html");

	int value = Integer.valueOf(request.getParameter("Value1"));

	System.out.println("service(): id = " + this.toString());
	for(int i = 0; i < value; i++) {
		System.out.println("service() loop: id = " + this.toString() + "; i = " + i);
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

}

Po prostu tym kodem przekreśliłem swoją wiedzę teoretyczną na temat servletów.
Dlaczego drugi i każdy następny klient czeka na zakończenie wątku?
Dlaczego Tomcat apache-tomcat-6.0.20 w konfiguracji podstawowej nie zapewnia domyślnie MultiThreadModel?
Czy ktoś spotkał się z podobną sytuacją i wie jak temu zaradzić?

1 użytkowników online, w tym zalogowanych: 0, gości: 1