/*
* $Id: SessionServer.java,v 1.4 2002/09/16 08:05:07 jkl Exp $
*
* Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
*
* Use is subject to license terms, as defined in
* Anvil Sofware License, Version 1.1. See LICENSE
* file, or http://njet.org/license-1.1.txt
*/
package anvil.session.net;
import anvil.Log;
import anvil.server.Zone;
import anvil.server.SessionContainerPreferences;
import anvil.java.lang.ThreadPool;
import anvil.java.lang.Task;
import java.util.HashSet;
import java.util.StringTokenizer;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.io.IOException;
import java.io.InterruptedIOException;
/**
* class Listener
*
* @author: Jani Lehtim�ki
*/
public class SessionServer implements Runnable
{
protected ServerSessionContainer _container;
protected HashSet _allow = new HashSet();
protected Zone _zone;
protected ThreadPool _pool = new ThreadPool();
protected int _port = 8090;
protected Thread _listener = null;
protected InetAddress _address = null;
protected boolean _running = false;
public SessionServer(ServerSessionContainer container, Zone zone)
{
_container = container;
_zone = zone;
SessionContainerPreferences prefs = zone.getSessionContainerPreferences();
String allow = prefs.getPreference("allow", "").toString();
StringTokenizer tokenizer = new StringTokenizer(allow, " \t");
while(tokenizer.hasMoreTokens()) {
String hostname = tokenizer.nextToken();
try {
_allow.add(InetAddress.getByName(hostname));
} catch (UnknownHostException e) {
log().info("Unknown host '"+hostname+"' in 'allow' attribute");
}
}
_port = prefs.getIntPreference("port", 9000);
_pool.setMaxThreads(prefs.getIntPreference("maxthreads", 10));
_pool.setMaxTasks(prefs.getIntPreference("maxtasks", 30));
}
public ServerSessionContainer getContainer()
{
return _container;
}
public Log log()
{
return _zone.log();
}
public Zone getZone()
{
return _zone;
}
public synchronized void start()
{
if (_running) {
return;
}
_running = true;
_listener = new Thread(this, "SessionServer:"+_port);
_listener.start();
}
public synchronized void stop()
{
if (!_running) {
return;
}
_running = false;
_pool.shutdown();
_listener.interrupt();
try {
/* serversocket.accept() with SO_TIMEOUT=0 seems to hang:
so lets connect to it in order to wake it up */
InetAddress address = _address;
if (address != null) {
Socket socket = null;
try {
socket = new Socket(address, _port);
socket.setSoTimeout(30);
socket.getInputStream().close();
} catch (Throwable t) {
} finally {
if (socket != null) {
try {
socket.close();
} catch (Throwable t) {
}
}
}
}
_listener.join();
_allow.clear();
_allow = null;
} catch (InterruptedException e) {
}
}
public void run()
{
try {
ServerSocket serverSocket = null;
while(_running) {
if (serverSocket == null) {
try {
serverSocket = new ServerSocket(_port, 4);
_address = serverSocket.getInetAddress();
serverSocket.setSoTimeout(0);
} catch (IOException e) {
log().error("Cannot establish end point", e);
break;
}
log().info("Endpoint created at port "+_port);
}
try {
Socket socket = serverSocket.accept();
InetAddress address = socket.getInetAddress();
if (_running && _allow.contains(address)) {
_pool.spawn(new SessionClient(this, socket));
} else {
log().info("Connection from "+address.getHostName()+" rejected");
try {
socket.close();
} catch (Throwable t) {
}
}
} catch (InterruptedIOException e) {
} catch (IOException e) {
log().error(e);
try {
serverSocket.close();
} catch (Throwable t) {
}
serverSocket = null;
_address = null;
}
}
if (serverSocket != null) {
log().info("Endpoint at port "+_port+" closed");
serverSocket.close();
}
} catch (IOException e) {
log().error(e);
}
}
}