-----------------------------------------------------------------------------------
-------- 三、服务器部分:(test.qq.server) -----------------------
-----------------------------------------------------------------------------------
3.1 服务器主类Main入口类:
---------------------------------------------------------------------------------------
public class ServerMain {
public static void main(String[] args) {
QQServer ser = new QQServer();
System.out.println("服务器启动了...");
ser.startServer();
}
}
3.2 QQ服务器端:
---------------------------------------------------------------------------------------
/**
* QQ服务器端
*/
public class QQServer {
//好友列表
public Map<String,Socket> allClientSockets = new HashMap<String,Socket>();
/**
* 开启服务器
*/
public void startServer()
{
try
{
ServerSocket ss = new ServerSocket(8888);
while(true)
{
//有人上线,有新连接
Socket s = ss.accept();
//添加到连接列表
allClientSockets.put(Util.getClientInfo(s),s);
//群发好友列表(有人上线,群发一下好友列表,让客户端更新)
new ClientMsgReceiver(s , this).start();
broadcastFriendListToAllClient();
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
/**
* 提取所有客户端用户信息列表
*/
public ArrayList<String> getFrinendList()
{
return new ArrayList<String>(allClientSockets.keySet());
}
/**
* 发送消息给所有的客户端
*/
public void broadcastMassageToAllClient(byte[] serverToClientMsgBytes) {
Collection<Socket> ss = allClientSockets.values();
for (Socket socket : ss) {
try {
OutputStream os = socket.getOutputStream();
os.write(serverToClientMsgBytes);
os.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 群发好友列表
*/
public void broadcastFriendListToAllClient()
{
byte [] bs = MessageFactory.popServerFriends(getFrinendList());
broadcastMassageToAllClient(bs);
}
/**
* 在好友列表中删除掉线的客户端
*/
public void removeFriend(String clientInfo) {
if(allClientSockets.containsKey(clientInfo))
{
allClientSockets.remove(clientInfo);
}
}
}
3.3 与每个链接的客户端进行通信的类
---------------------------------------------------------------------------------------
/**
* 服务器开辟的线程,用来与单个客户端进行通信
* 每有一个客户端连接服务器,就会产生这样一个和客户端进行连接通信的线程
* 有多少客户端就有多少这个线程
* 保证了客户端可以和所有的线程进行通信
*/
public class ClientMsgReceiver extends Thread
{
//与客户端进行通信的socket
private Socket clientSocket;
//与客户端进行通信的输入流(客户端输入进来的)
private InputStream is;
//与客户端进行通信的输出流(输出信息到客户端)
private OutputStream os;
//唯一的服务器本身
private QQServer qqServer;
//本线程连接的客户端信息
private String clientInfo;
public ClientMsgReceiver(Socket s , QQServer ser) {
try {
this.clientSocket = s;
this.qqServer = ser;
this.is = clientSocket.getInputStream();
this.os = clientSocket.getOutputStream();
this.clientInfo = Util.getClientInfo(clientSocket);
} catch (Exception e) {
e.printStackTrace();
}
}
public void run(){
try {
//与客户端进行通讯
while(true)
{
//解析流
Message msg = MessageFactory.parseMessageFromInputStream(is);
//客户端请求刷新好友列表
if(msg.getClass() == ClientReflashFriendsListMessage.class)
{
//TODO 获取好友列表,并发送给所有客户端()
os.write(MessageFactory.popServerFriends(qqServer.getFrinendList()));
os.flush();
}
//如果是客户端发来的聊天信息--群聊
else if(msg.getClass() == ClientSendChatMessage.class)
{
//客户端聊天信息
ClientSendChatMessage msg1 = (ClientSendChatMessage)msg;
byte [] chat = msg1.getMessageContent();
//服务器进行组装(添加用户信息。然后转发所有人),得到byte[]
byte [] serverToClientMsgBytes = MessageFactory.popServerChatMessage(clientInfo, chat);
//群发给所有客户端
qqServer.broadcastMassageToAllClient(serverToClientMsgBytes);
}
//如果是客户端发来的聊天信息--私聊
else if(msg.getClass() == ClientSendChatMessageSingle.class)
{
//客户端聊天信息
ClientSendChatMessageSingle msg1 = (ClientSendChatMessageSingle)msg;
ChatSingleBean chat = msg1.getMessageContent();
String reveInfo = chat.getReceiver();
//组装消息
byte [] serverToClientMsgBytes = MessageFactory.popServerChatMessageSingle(clientInfo, chat.getChat());
//获取发送方的socket
Socket sock = qqServer.allClientSockets.get(reveInfo);
OutputStream out = sock.getOutputStream();
out.write(serverToClientMsgBytes);
out.flush();
}
}
}
catch(Exception e)
{
//客户端掉线了,要删除
qqServer.removeFriend(clientInfo);
qqServer.broadcastFriendListToAllClient();
//e.printStackTrace();
}
}
}