【Java】JavaSocket编程开发聊天室-服务器端部分

Server服务器端.

服务器是计算机的一种,它比普通计算机运行更快、负载更高、价格更贵。服务器在网络中为其它客户机(如PC机、智能手机、ATM等终端甚至是火车系统等大型设备)提供计算或者应用服务。服务器具有高速的CPU运算能力、长时间的可靠运行、强大的I/O外部数据吞吐能力以及更好的扩展性。根据服务器所提供的服务,一般来说服务器都具备承担响应服务请求、承担服务、保障服务的能力。服务器作为电子设备,其内部的结构十分的复杂,但与普通的计算机内部结构相差不大,如:cpu、硬盘、内存,系统、系统总线等。

ServerLauncher.

ServerLauncher是管理员看到的服务器端界面的启动器,当管理员运行ServerLauncher时,有启动一个进程来对于从属性文件中预先配置的端口号到达的用户进行监听,对应于每一个到达的用户,都启动一个对应的进程为其服务。

int ServerPort = Integer.parseInt(getProperty("Port"));
serverSocket = new ServerSocket(ServerPort);

Socket socket = serverSocket.accept();
			
//Create a new thread.			
new Thread(socket).start();

并且在ServerLauncher中也对整个服务器端的UI风格进行了设置,同样使用了Java独特的跨平台界面风格:

JFrame.setDefaultLookAndFeelDecorated(true);
JDialog.setDefaultLookAndFeelDecorated(true);

UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());

//Display server UI.
new ServerUI()

ServerUI.

ServerUI是表示管理员实际上看到的图形界面的类,其中包括了在线用户列表、已注册用户列表的显示、管理员广播功能、管理员私聊用户功能以及管理员强制用户下线功能的控件与实现。最终的GUI界面如下所示,并且我们从GUI入手,逐步讲述功能以及有关控件的实现细节:
在这里插入图片描述

管理员广播功能

这一功能其实并不是很复杂,它和某一个用户在群聊中发送消息并没有什么不同,只不过现在这一"用户"的身份比较特殊,它代表了聊天室系统本身。获取了ServerUI界面上管理员编辑完成的广播消息内容之后,服务器端就向每一个客户端发送一个标记为【广播】回复,而客户端对于这样的消息处理和标记为【聊天】的消息处理并没有不同,只需要显示在用户看到的界面上即可。下面我们给出展示逻辑的代码,以及广播功能的展示:

//Special user:system.
ADT_of_User system = new ADT_of_User(8888,"system");

//Set sender with system.
Message message = new Message();
message.setSender(system);

//Mark reply with 'BROADCAST'.
reply.setType(ReplyType.BROADCAST);

//Reply to every client.
SendReplyOfficial(ServerDataStore.OnlineInfoMap.get(ID),reply);

在这里插入图片描述
在这里插入图片描述
两个在线的用户显然都收到了来自System的信息"We are under attack".

JTabbedPane的使用

选项卡面板是指ServerUI右侧那块,根据管理员的选择呈现出不同内容的部分:
在这里插入图片描述在这里插入图片描述
如上图所示,分别能够显示出OnlineUsers以及RegisteredUsers,选项卡面板的代码部分如下所示(注意其中的变量OnlineUsers和RegisteredUsers都已继承自AbstractTableModel的类的实例化,所以能够基于它们构造出JTable类型的变量供后续的addTab操作):

//Create a JTabbedPane.
JTabbedPane TabbedPane = new JTabbedPane();

//Get online users and registered users's data,and convert to JTable.
OnlineUsersTable = new JTable(OnlineUsers);
RegistedUsersTable = new JTable(RegisteredUsers);

//Add tab.
TabbedPane.addTab("OnlineUsersList", new JScrollPane(OnlineUsersTable));
TabbedPane.addTab("RegistedUsersList", new JScrollPane(RegistedUsersTable));

JPopupMenu的使用

顾名思义,这是一种弹出式的菜单,能够提供一些自定义的功能,在ServerUI的界面上,管理员能够选择某一个在线用户,进行【私聊】或者【强制下线】操作。
在这里插入图片描述
前面我们以及说过,此处JTabbedPane中的选项卡中的元素都是JTable类型的,并且其中实际的数据也是早已保存在服务器端的,所以剩下的问题就是,如何在JTable类型上添加进弹出式的菜单呢?我们只需要创建一个JPopupMenu,向其中加入绑定了对应动作的JMenuItem,最后再将JPopupMenu添加到JTable中即可,是一个层层包含的关系。

//Create JPopupMenu and JMenuItem respectfully.
JPopupMenu PopupMenu = new JPopupMenu();
JMenuItem SendItem = new JMenuItem("SendMessage");
JMenuItem KickOutItem = new JMenuItem("KickOut");
		
//Set command for distinguish.
SendItem.setActionCommand("SendMessage");
KickOutItem.setActionCommand("KickOut");

//Create ActionListener.
ActionListener Do = new ActionListener()
{
	@Override
	public void actionPerformed(ActionEvent e)
	{
		//Get command.
		String command = e.getActionCommand();
		
		//Conduct differet action via difference between commands.
		ConductCommand(command);
	}
};

//Add actionListener
SendItem.addActionListener(Do);
KickOutItem.addActionListener(Do);

//Add menu item into popup menu.
PopupMenu.add(SendItem);
PopupMenu.add(KickOutItem);

//Add popup menu into table.
OnlineUsersTable.setComponentPopupMenu(PopupMenu);

管理员私聊功能

这一功能和前面叙述过的聊天室中群聊消息的发送、管理员广播功能的实现大同小异。只不过现在的用户是特殊的用户’System’,原理还是服务器端获得了被私聊用户的ID以后,向其发送一个标记为【聊天】的回复,后续该用户的客户端像对待普通消息那样处理这一回复。

//Create user 'System'
ADT_of_User system = new ADT_of_User(8888,"system");
Message message = new Message();

//Set sender and receiver.
message.setSender(system);
message.setReceiver(ThatUser);

//Mark reply with 'CHAT'.
Reply reply = new Reply();
reply.setType(ReplyType.CHAT);

//Reply to receiver.
ServerRecordClient receiver = get(message.getReceiver().getID());
SendReply(receiver,reply);

作为测试,我们让管理员System给Hoe发送了一条系统通知,只有Hoe能看到这条消息,在线的其他用户是无法看到的。
在这里插入图片描述
Hoe的确收到了这条消息,而Mega的界面中没有这条消息:
在这里插入图片描述
在这里插入图片描述

管理员强制下线功能

强制下线功能只需要服务器向被选中用户的客户端发送一个标记为【退出】的回复,客户端收到这样的回复之后,就会自动关闭,从而完成了管理员强制下线的功能。

//Create user 'System'
ADT_of_User system = new ADT_of_User(8888,"system");
Message message = new Message();

//Set sender and receiver.
message.setSender(system);
message.setReceiver(KickedUser);

//Mark reply with 'KICK_OUT'.
Reply reply = new Reply();
reply.setType(ReplyType.KICK_OUT);

//Reply to receiver.
ServerRecordClient receiver = get(message.getReceiver().getID());
SendReply(receiver,reply);

我们让管理员向Mega执行强制下线功能,结果如下所示:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_44246009/article/details/107446287