import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.RemoteException;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.*;
//import TimeProvider;
public class TimeServer extends UnicastRemoteObject implements java.io.Serializable,TimeServerInterface
{
private static final long serialVersionUID = 1L;
LinkedList<TimeClientInterface> subscriberList = new LinkedList<TimeClientInterface>();//TimeSubscriber表
public GraphicServerInterface graphic_interface = null;
private Timer timer = null;
private int count = 0;// 计数器,以秒为单位
private int clientCnt = 0;// 连接的客户端数量
private boolean server_bound = false; // 服务是否已注册绑定
// 更新客户端连接数
public void updateClinetCnt(int count)
{
clientCnt += count;
graphic_interface.LShowClientCnt.setText("The total count of the clients connected is " + clientCnt);
}
// 客户端连接服务器
public void Attach(TimeClientInterface time_subscriber)throws RemoteException
{
subscriberList.add(time_subscriber);
updateClinetCnt(1);
System.out.println("A new time subscriber has connected.");
}
//客户端断开连接
public void Detach(TimeClientInterface time_subscriber)throws RemoteException
{
if(subscriberList.remove(time_subscriber))
{
updateClinetCnt(-1);
System.out.println("A time subscriber has disconnected.");
}
else
{
System.out.println("Disconnection failed!");
}
}
//通知客户端更新时间
public void Notify()throws RemoteException
{
if(subscriberList.isEmpty()) //无客户端连接,返回
{
return;
}
ListIterator<TimeClientInterface> subscriberLI = subscriberList.listIterator();
TimeClientInterface time_subscriber = null;
while(subscriberLI.hasNext())
{
time_subscriber = (TimeClientInterface)subscriberLI.next();
if(count % time_subscriber.GetInterval() == 0)
{
time_subscriber.Update(new Date());
}
}
++count;
if(count % 3600 == 0) //计数器每小时清零一次
{
count = 0;
}
}
// 终止服务
public void Terminate() throws RemoteException
{
if(!server_bound)
{
return;// 服务已终止,返回
}
if(!subscriberList.isEmpty()) //无客户端连接,返回
{
timer.cancel();// 停止服务器和客户端的时间更新
ListIterator<TimeClientInterface> subscriberLI = subscriberList.listIterator();
TimeClientInterface time_subscriber = null;
while(subscriberLI.hasNext())
{
time_subscriber = (TimeClientInterface)subscriberLI.next();
time_subscriber.Terminate();// 断开每个客户端
}
subscriberList.clear();// 清空客户端列表
}
try {
Naming.unbind("//localhost:1099/TimeServer");// 终止服务绑定
server_bound = false;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (NotBoundException e) {
e.printStackTrace();
}
updateClinetCnt(-clientCnt);
}
//定时任务
class TaskTicker extends TimerTask
{
public void run()
{
try
{
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
graphic_interface.LShowCurTime.setText(formatter.format(new Date()));// 更新服务器显示时间
Notify();
}
catch(RemoteException re)
{
System.out.println("Remote exception" + re.toString());
}
}
}
public TimeServer() throws RemoteException,MalformedURLException
{
graphic_interface = new GraphicServerInterface();
}
public static void main(String args[])throws RemoteException,MalformedURLException
{
final TimeServer time_Server = new TimeServer();
//关闭服务器前检查是否还有客户端连接,若有,关闭之
Runtime.getRuntime().addShutdownHook(new Thread()
{
public void run()
{
try {
time_Server.Terminate();
} catch (RemoteException e) {
System.out.println("Remote eexception" + e.toString());
}
}
});
}
class GraphicServerInterface extends Frame
{
private static final long serialVersionUID = 1L;
Panel PInformation;
Panel PShowClientCnt;
Panel PButton;
Label LIP;
Label LCurTime;
Label LShowClientCnt;
Label LShowIP;
Label LShowCurTime;
//Label LClientCnt;
Button Start, Stop;
public GraphicServerInterface()
{
setTitle("Server");
addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
try {
Terminate();
} catch (RemoteException e1) {
System.out.println( "Remote exception" + e1.toString());
}
dispose();
System.exit(1);
}
});
setLocation(250,250);
setSize(600,480);
setResizable(false);
PInformation = new Panel();
PInformation.setLayout(new GridLayout(1, 5));
PInformation.setBackground(new Color(255,253,225));
PShowClientCnt = new Panel();
PShowClientCnt.setLayout(new GridLayout(2, 1));
PShowClientCnt.setBackground(new Color(255,253,225));
PButton = new Panel();
PButton.setLayout(new GridLayout(1, 2));
PButton.setBackground(new Color(255,253,225));
//服务启动连接按钮
Start = new Button("Start");
Start.setFont(new Font("Times New Roman",Font.PLAIN,12));
Start.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
try
{
Naming.rebind("rmi://localhost:1099/TimeServer", TimeServer.this);
System.out.println("Server is ready!");
timer = new Timer();
timer.scheduleAtFixedRate(new TaskTicker(),1000,1000);//一秒一次
server_bound = true;
Start.setEnabled(false);
Stop.setEnabled(true);
}
catch(Exception e)
{
System.out.println( "dd"+e.toString());
}
}
});
//断开服务器
Stop = new Button("ShutDown");
Stop.setFont(new Font("Times New Roman",Font.PLAIN,12));
Stop.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
try{
Terminate();
Start.setEnabled(true);
Stop.setEnabled(false);
System.out.println( "Server has been shut down!");
}
catch(RemoteException re)
{
System.out.println( "Remote exception" + re.toString());
}
}
});
Stop.setEnabled(false);
LIP=new Label("Local IP:");
LIP.setFont(new Font("Times New Roman",Font.BOLD,15));
LIP.setAlignment(1);
LCurTime = new Label("Current Time: ");
LCurTime.setFont(new Font("Times New Roman", Font.BOLD, 15));
LCurTime.setAlignment(1);
String localIP = "127.0.0.1";
try {
localIP = InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException e1) {
System.out.println("The IP of localhost is unknown!");
}
LShowIP = new Label(localIP);
LShowIP.setAlignment(1);
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
LShowCurTime = new Label(formatter.format(new Date()));
LShowCurTime.setAlignment(1);