public class ServerCenter implements Server{
private static HashMap<String, Class> serviceRegiser = new HashMap<>();
private static int port;
public ServerCenter() {
}
public ServerCenter(int port) {
this.port = port;
}
//开启服务
@Override
public void start(){
ServerSocket server = null;
Socket socket = null;
ObjectInputStream input = null;
ObjectOutputStream output = null;
try {
server = new ServerSocket();
server.bind(new InetSocketAddress(port));
socket = server.accept(); //等待客户端连接
//接受到客户端连接及请求,处理该请求
input = new ObjectInputStream(socket.getInputStream());
//因为ObjectInputStream对发送数据的顺序严格要求,因此需要按照发送的顺序逐个接受
String serviceName = input.readUTF();
String methodName = input.readUTF();
Class[] parameterTypes = (Class[])input.readObject();
Object[] arguments = (Object[])input.readObject();
Class serviceClass = serviceRegiser.get(serviceName);
Method method = serviceClass.getMethod(methodName, parameterTypes);
Object result = method.invoke(serviceClass.newInstance(), arguments);
//将服务端执行完毕的返回值返回给客户端
output = new ObjectOutputStream(socket.getOutputStream());
output.writeObject(result);
}catch (Exception e) {
e.printStackTrace();
}finally {
try {
if(null != output) {
output.close();
}
if(null != input) {
input.close();
}
}catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
public void stop() {
}
@Override
public void register(Class service, Class serviceImpl) {
serviceRegiser.put(service.getName(), serviceImpl);
}
}
4.优化
在服务端建立连接池,使服务能够多线程并发执行
public class ServerCenter implements Server{
private static HashMap<String, Class> serviceRegiser = new HashMap<>();
private static int port;
private static ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
private static boolean isRunning = false;
public ServerCenter() {
}
public ServerCenter(int port) {
this.port = port;
}
//开启服务
@Override
public void start(){
ServerSocket server = null;
try {
server = new ServerSocket();
server.bind(new InetSocketAddress(port));
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Socket socket = null;
System.out.println("启动服务...");
isRunning = true;
while(true) {
try {
socket = server.accept();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} //等待客户端连接
executor.execute(new ServiceTask(socket));
}
}
@Override
public void stop() {
System.out.println("关闭服务...");
isRunning = false;
executor.shutdown();
}
@Override
public void register(Class service, Class serviceImpl) {
serviceRegiser.put(service.getName(), serviceImpl);
}
private static class ServiceTask implements Runnable{
Socket socket = new Socket();
public ServiceTask() {}
public ServiceTask(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
ObjectInputStream input = null;
ObjectOutputStream output = null;
try {
//接受到客户端连接及请求,处理该请求
input = new ObjectInputStream(socket.getInputStream());
//因为ObjectInputStream对发送数据的顺序严格要求,因此需要按照发送的顺序逐个接受
String serviceName = input.readUTF();
String methodName = input.readUTF();
Class[] parameterTypes = (Class[])input.readObject();
Object[] arguments = (Object[])input.readObject();
Class serviceClass = serviceRegiser.get(serviceName);
Method method = serviceClass.getMethod(methodName, parameterTypes);
Object result = method.invoke(serviceClass.newInstance(), arguments);
//将服务端执行完毕的返回值返回给客户端
output = new ObjectOutputStream(socket.getOutputStream());
output.writeObject(result);
}catch (Exception e) {
e.printStackTrace();
}finally {
try {
if(null != output) {
output.close();
}
if(null != input) {
input.close();
}
}catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
使用线程启动服务
public class RPCServerTest {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
Server server = new ServerCenter(9999);
server.register(HelloService.class, HelloServiceImpl.class);
server.start();
}
}).start();;
}
}
客户端测试代码
public class RPCClientTest {
public static void main(String[] args) throws ClassNotFoundException {
HelloService service = Client.getRemoteProxyObj(Class.forName("com.kexing.rpc.service.HelloService"), new InetSocketAddress("127.0.0.1", 9999));
System.out.println(service.sayHi("zs"));
}
}