P6 服务器API层
1 服务器 Server类
package com.mec.csframework.core;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import com.my.util.IListener;
import com.my.util.ISpeaker;
public class Server implements Runnable,ISpeaker{
public static final String SERVER = "SERVER";
public static final int DEFAULT_MAX_CLIENT_COUNT = 20;
private int port;
private ServerSocket server;
private volatile boolean goon;
private ServerConversationPool clientPool;
private int maxClientCount;
private IServerAction serverAction;
IServerAction getServerAction() {
return serverAction;
}
public void setServerAction(IServerAction serverAction) {
this.serverAction = serverAction;
}
private List<IListener> listenerList;
public Server() {
this.port = INetConfig.port;
this.maxClientCount = DEFAULT_MAX_CLIENT_COUNT;
this.listenerList = new ArrayList<IListener>();
this.serverAction = new ServerActionAdapter();
}
public void setMaxClientCount(int maxClientCount) {
this.maxClientCount = maxClientCount;
}
public void setPort(int port) {
this.port = port;
}
public void startUp() {
if(this.goon == true) {
speakOut("服务器已启动");
return;
}
try {
this.server = new ServerSocket(this.port);
speakOut("服务器已启动");
this.clientPool = new ServerConversationPool();
this.goon = true;
new Thread(this).start();
} catch (IOException e) {
speakOut("服务器启动异常");
}
}
public void close() {
this.goon = false;
try {
if(server != null && !server.isClosed()) {
this.server.close();
}
} catch (IOException e) {
} finally {
this.server = null;
}
}
public void shutDown() {
if(!this.goon) {
speakOut("服务器尚未启动");
return;
}
if(this.clientPool.isEmpty()) {
speakOut("尚有在线的客户端,不能宕机");
return;
}
close();
}
public void forceDown() {
if(!this.goon){
speakOut("服务器尚未启动");
return;
}
List<ServerConversation> clientList = this.clientPool.getClient();
for(ServerConversation client : clientList) {
client.forceDown();
}
close();
speakOut("服务器强制宕机");
}
public void killClient(String clientId, String reason) {
ServerConversation client = this.clientPool.getClient(clientId);
client.killClient(reason);
}
public List<String> getOnLineClientList() {
List<String> clientList = new ArrayList<>();
List<ServerConversation> onLineClientList = this.clientPool.getClient();
for(ServerConversation client : onLineClientList) {
clientList.add(client.getIp() + ":" + client.getId());
}
return clientList;
}
void messageFromClient(String clientId, String message) {
this.serverAction.dealMessageFromClient(clientId, message);
}
@Override
public void run() {
speakOut("服务器开始侦听客户端连接请求");
while(this.goon) {
try {
Socket socket = this.server.accept();
ServerConversation client = new ServerConversation(socket, this);
if(this.clientPool.getClientCount() > this.maxClientCount) {
client.OutOfRoom();
continue;
}
client.createClientId();
this.clientPool.addClient(client);
} catch (IOException e) {
this.goon = false;
}
}
speakOut("结束侦听客户端连接");
close();
}
void toOne(String sourceId, String targetId, String message) {
ServerConversation targetClient = this.clientPool.getClient(targetId);
targetClient.toOne(sourceId, message);
}
void toOther(String sourceId, String message) {
List<ServerConversation> clientList = this.clientPool.getClientExcept(sourceId);
for(ServerConversation client : clientList) {
client.toOther(sourceId, message);
}
}
void clientOffLine(String clientId) {
this.clientPool.removeClient(clientId);
}
@Override
public void addListener(IListener listener) {
if(this.listenerList.contains(listener)) {
return;
}
this.listenerList.add(listener);
}
@Override
public void removeListener(IListener listener) {
if(!this.listenerList.contains(listener)){
return;
}
this.listenerList.remove(listener);
}
@Override
public void speakOut(String message) {
for(IListener listener : this.listenerList) {
listener.readMessage(message);
}
}
}
2 留给服务器APP层待处理的方法
(1) IServerAction接口

(2) ServerActionAdapter适配器

P7 客户端API层
1 客户端 Client类
package com.mec.csframework.core;
import java.io.IOException;
import java.net.Socket;
public class Client {
private String ip;
private int port;
private Socket socket;
private ClientConversation conversation;
private IClientAction clientAction;
public String getId() {
return conversation.getId();
}
public Client() {
this.ip = INetConfig.ip;
this.port = INetConfig.port;
this.clientAction = new ClientActionAdapter();
}
public void setClientAction(IClientAction clientAction) {
this.clientAction = clientAction;
}
IClientAction getClientAction() {
return clientAction;
}
public boolean connectToServer() {
try {
this.socket = new Socket(this.ip, this.port);
this.conversation = new ClientConversation(socket, this);
} catch (IOException e) {
return false;
}
return false;
}
public void toOne(String targetId, String message) {
this.conversation.toOne(targetId, message);
}
public void toOther(String message) {
this.conversation.toOther(message);
}
public void messageToServer(String message) {
this.conversation.messageToServer(message);
}
public void offLine() {
if(this.clientAction.confirmOffLine()) {
this.clientAction.beforeOffLine();
this.conversation.offLine();
this.clientAction.afterOffLine();
}
}
}
2 留给客户端APP层待处理的方法
(1) IClientAction接口

(2) ClientActionAdapter适配器
