package com.chat.server;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;
import java.util.Vector;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import com.chat.bean.Account;
import com.chat.bean.Chat;
import com.chat.bean.Logs;
import com.chat.dao.AccountDAO;
import com.chat.dao.imp.AccountDAOImp;
import com.chat.util.Factory;
public class ServerFrame extends JFrame implements ActionListener{
// 选项卡控件
JTabbedPane tp1 = new JTabbedPane();
JSplitPane jp1;// 左边的选项卡
JPanel jp2;// 右边的选项卡
JLabel jlState, jlCurrent, jlMax, jlServer, jlIP, jlProtocol, jlPort;
JTextField jtState, jtCurrent, jtMax, jtServer, jtIP, jtProtocol, jtPort;
JLabel jlLog;
JTextArea jtLog;// 服务器日志
JTextArea jtMsg;// 用户消息
JList list;// 在线用户列表
DefaultListModel model;
JTextField jtNotice;// 通知
JButton bSend, bKs;// 发送、踢人
JPanel jpLeft, jpRight;
private Hashtable<String, ObjectOutputStream> ht_users=new Hashtable<String, ObjectOutputStream>();
private static int count=0;
public ServerFrame() {
super("服务器");
//this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//窗体关闭事件
this.addWindowListener(new MyWindow());
// 服务器管理选项卡面板
jp1 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
jp1.setDividerSize(5);
jlState = new JLabel("当前状态:");
jtState = new JTextField(10);
jtState.setText("已启动...");
jlCurrent = new JLabel("当前在线人数:");
jtCurrent = new JTextField(10);
jtCurrent.setText("0");// 当前在线人数为0
jlMax = new JLabel("最多在线人数:");
jtMax = new JTextField(10);
jtMax.setText("50人");
jlServer = new JLabel("服务器名称:");
jtServer = new JTextField(10);
try {
jtServer.setText(InetAddress.getLocalHost().getHostName());
} catch (UnknownHostException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
jlProtocol = new JLabel("访问协议:");
jtProtocol = new JTextField(10);
jtProtocol.setText("HTTP");
jlIP = new JLabel("服务器IP");
jtIP = new JTextField(10);
try {
jtIP.setText(InetAddress.getLocalHost().getHostAddress());
} catch (UnknownHostException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
jlPort = new JLabel("服务器端口");
jtPort = new JTextField(10);
jtPort.setText("8888");
// 服务器管理左边的面板
jpLeft = new JPanel();
jpLeft.setLayout(new GridLayout(14, 1));
jpLeft.add(jlState);
jpLeft.add(jtState);
jpLeft.add(jlCurrent);
jpLeft.add(jtCurrent);
jpLeft.add(jlMax);
jpLeft.add(jtMax);
jpLeft.add(jlServer);
jpLeft.add(jtServer);
jpLeft.add(jlProtocol);
jpLeft.add(jtProtocol);
jpLeft.add(jlIP);
jpLeft.add(jtIP);
jpLeft.add(jlPort);
jpLeft.add(jtPort);
// 服务器管理右边的面板
jlLog = new JLabel(" [服务器日志]");
jtLog = new JTextArea();
jpRight = new JPanel();
jpRight.setLayout(new BorderLayout());
jpRight.add(jlLog, BorderLayout.NORTH);
jpRight.add(new JScrollPane(jtLog), BorderLayout.CENTER);
// 添加到分割面板
jp1.add(jpLeft);
jp1.add(jpRight);
// 用户信息管理选项卡面板
jp2 = new JPanel();
// 设置为边框布局
jp2.setLayout(new BorderLayout());
// 用户消息面板
JPanel jp21 = new JPanel();
jp21.setLayout(new BorderLayout());
jp21.add(new JLabel("[用户消息]"), BorderLayout.NORTH);
// 用户消息
jtMsg = new JTextArea();
jp21.add(new JScrollPane(jtMsg), BorderLayout.CENTER);
JPanel jp22 = new JPanel();
jp22.setLayout(new BorderLayout());
jp22.add(new JLabel("[在线用户列表]"), BorderLayout.NORTH);
// 在线用户列表
model = new DefaultListModel();
list = new JList(model);
jp22.add(new JScrollPane(list), BorderLayout.CENTER);
JPanel jp23 = new JPanel();
jp23.add(new JLabel("通知:"));
jtNotice = new JTextField(15);
bSend = new JButton("发送(S)");
bSend.addActionListener(this);
bKs = new JButton("踢人(K)");
bKs.addActionListener(this);
jp23.add(jtNotice);
jp23.add(bSend);
jp23.add(bKs);
jp2.add(jp21, BorderLayout.CENTER);
jp2.add(jp22, BorderLayout.EAST);
jp2.add(jp23, BorderLayout.SOUTH);
tp1.add(jp1, "服务器管理");
tp1.add(jp2, "用户信息管理");
this.getContentPane().add(tp1);
this.setLocation(300, 200);
this.setSize(700, 600);
this.setVisible(true);
try {
ServerSocket ss=new ServerSocket(8888);
while(true)
{
Socket s= ss.accept();
//启动线程
new ServerThread(s).start();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//创建线程,接受某个客户端的消息,并转发
class ServerThread extends Thread
{
Socket s;
public ServerThread(Socket s)
{
this.s=s;
}
@Override
public void run() {
try {
//获取输入流
InputStream in=s.getInputStream();
//转换成对象流
ObjectInputStream ois=new ObjectInputStream(in);
//获取输出流
OutputStream os=s.getOutputStream();
//转换成对象流
ObjectOutputStream oos=new ObjectOutputStream(os);
while(true)
{
Object obj= ois.readObject();
Chat ch=(Chat)obj;
AccountDAO dao=new AccountDAOImp();
if(ch.getFlag()==Chat.LOGIN)//上线的消息
{
Account acc=(Account)ch;
System.out.println(acc.getAccount()+"上线");
//将该用户的状态改为上线
dao.updateStatus(acc.getAccount(), 2);
//修改在线人数
count++;
jtCurrent.setText(""+count);
//设置日志
jtLog.append(Factory.getTime()+" \n"+" "+acc.getAccount()+"【"+acc.getUsername()+"】上线\n");
//将该用户添加到在线用户列表中
model.addElement(acc.getAccount());
//给每个在线的用户发送该用户上线的消息
Collection<ObjectOutputStream> v= ht_users.values();
Iterator<ObjectOutputStream> it= v.iterator();
Chat ch1=new Chat();
ch1.setMessage(Factory.getTime()+" \n"+" "+acc.getAccount()+"【"+acc.getUsername()+"】上线\n");
ch1.setFlag(Chat.NOTICE);
while(it.hasNext())
{
ObjectOutputStream os1= it.next();
os1.writeObject(ch1);
}
//将当前上线的用户保存到Hashtable中
ht_users.put(acc.getAccount(), oos);
//通知每个在线用户更新自己的在线用户列表
NoticeUpdate();
}
else if(ch.getFlag()==Chat.LOGOUT)//下线的消息
{
Account acc=(Account)ch;
System.out.println(acc.getAccount()+"下线");
//将该用户的状态改为下线
dao.updateStatus(acc.getAccount(), 1);
//修改在线人数
count--;
jtCurrent.setText(""+count);
//设置日志
jtLog.append(Factory.getTime()+" \n"+" "+acc.getAccount()+"【"+acc.g