diff --git a/rpc-common/src/main/java/top/guoziyang/rpc/enumeration/ResponseCode.java b/rpc-common/src/main/java/top/guoziyang/rpc/enumeration/ResponseCode.java index aa0ea3c..4afba0f 100644 --- a/rpc-common/src/main/java/top/guoziyang/rpc/enumeration/ResponseCode.java +++ b/rpc-common/src/main/java/top/guoziyang/rpc/enumeration/ResponseCode.java @@ -13,8 +13,8 @@ public enum ResponseCode { SUCCESS(200,"调用方法成功"), FAIL(500,"调用方法失败"), - NOT_FOUND_METHOD(500,"未找到指定方法"), - NOT_FOUND_CLASS(500,"未找到指定类"); + METHOD_NOT_FOUND(500,"未找到指定方法"), + CLASS_NOT_FOUND(500,"未找到指定类"); private final int code; private final String message; diff --git a/rpc-common/src/main/java/top/guoziyang/rpc/enumeration/RpcError.java b/rpc-common/src/main/java/top/guoziyang/rpc/enumeration/RpcError.java new file mode 100644 index 0000000..ce5f4d9 --- /dev/null +++ b/rpc-common/src/main/java/top/guoziyang/rpc/enumeration/RpcError.java @@ -0,0 +1,18 @@ +package top.guoziyang.rpc.enumeration; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * @author ziyang + */ +@AllArgsConstructor +@Getter +public enum RpcError { + + SERVICE_INVOCATION_FAILURE("服务调用出现失败"), + SERVICE_CAN_NOT_BE_NULL("注册的服务不得为空"); + + private final String message; + +} diff --git a/rpc-common/src/main/java/top/guoziyang/rpc/exception/RpcException.java b/rpc-common/src/main/java/top/guoziyang/rpc/exception/RpcException.java new file mode 100644 index 0000000..d099c4f --- /dev/null +++ b/rpc-common/src/main/java/top/guoziyang/rpc/exception/RpcException.java @@ -0,0 +1,22 @@ +package top.guoziyang.rpc.exception; + +import top.guoziyang.rpc.enumeration.RpcError; + +/** + * @author ziyang + */ +public class RpcException extends RuntimeException { + + public RpcException(RpcError error, String detail) { + super(error.getMessage() + ": " + detail); + } + + public RpcException(String message, Throwable cause) { + super(message, cause); + } + + public RpcException(RpcError error) { + super(error.getMessage()); + } + +} diff --git a/rpc-core/src/main/java/top/guoziyang/rpc/client/RpcClient.java b/rpc-core/src/main/java/top/guoziyang/rpc/client/RpcClient.java index 6dddc74..3df6805 100644 --- a/rpc-core/src/main/java/top/guoziyang/rpc/client/RpcClient.java +++ b/rpc-core/src/main/java/top/guoziyang/rpc/client/RpcClient.java @@ -3,6 +3,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import top.guoziyang.rpc.entity.RpcRequest; +import top.guoziyang.rpc.entity.RpcResponse; +import top.guoziyang.rpc.enumeration.ResponseCode; +import top.guoziyang.rpc.enumeration.RpcError; +import top.guoziyang.rpc.exception.RpcException; import java.io.IOException; import java.io.ObjectInputStream; @@ -23,10 +27,19 @@ public Object sendRequest(RpcRequest rpcRequest, String host, int port) { ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream()); objectOutputStream.writeObject(rpcRequest); objectOutputStream.flush(); - return objectInputStream.readObject(); + RpcResponse rpcResponse = (RpcResponse) objectInputStream.readObject(); + if(rpcResponse == null) { + logger.error("服务调用失败,service:{}", rpcRequest.getInterfaceName()); + throw new RpcException(RpcError.SERVICE_INVOCATION_FAILURE, " service:" + rpcRequest.getInterfaceName()); + } + if(rpcResponse.getStatusCode() == null || rpcResponse.getStatusCode() != ResponseCode.SUCCESS.getCode()) { + logger.error("调用服务失败, service: {}, response:{}", rpcRequest.getInterfaceName(), rpcResponse); + throw new RpcException(RpcError.SERVICE_INVOCATION_FAILURE, " service:" + rpcRequest.getInterfaceName()); + } + return rpcResponse.getData(); } catch (IOException | ClassNotFoundException e) { logger.error("调用时有错误发生:", e); - return null; + throw new RpcException("服务调用失败: ", e); } } diff --git a/rpc-core/src/main/java/top/guoziyang/rpc/client/RpcClientProxy.java b/rpc-core/src/main/java/top/guoziyang/rpc/client/RpcClientProxy.java index ea5c598..6924d4a 100644 --- a/rpc-core/src/main/java/top/guoziyang/rpc/client/RpcClientProxy.java +++ b/rpc-core/src/main/java/top/guoziyang/rpc/client/RpcClientProxy.java @@ -1,5 +1,7 @@ package top.guoziyang.rpc.client; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import top.guoziyang.rpc.entity.RpcRequest; import top.guoziyang.rpc.entity.RpcResponse; @@ -13,6 +15,7 @@ */ public class RpcClientProxy implements InvocationHandler { + private static final Logger logger = LoggerFactory.getLogger(RpcClientProxy.class); private String host; private int port; @@ -28,6 +31,7 @@ public T getProxy(Class clazz) { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + logger.info("调用方法: {}#{}", method.getDeclaringClass().getName(), method.getName()); RpcRequest rpcRequest = RpcRequest.builder() .interfaceName(method.getDeclaringClass().getName()) .methodName(method.getName()) @@ -35,6 +39,6 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl .paramTypes(method.getParameterTypes()) .build(); RpcClient rpcClient = new RpcClient(); - return ((RpcResponse) rpcClient.sendRequest(rpcRequest, host, port)).getData(); + return rpcClient.sendRequest(rpcRequest, host, port); } } diff --git a/rpc-core/src/main/java/top/guoziyang/rpc/server/WorkerThread.java b/rpc-core/src/main/java/top/guoziyang/rpc/server/RequestHandler.java similarity index 53% rename from rpc-core/src/main/java/top/guoziyang/rpc/server/WorkerThread.java rename to rpc-core/src/main/java/top/guoziyang/rpc/server/RequestHandler.java index 02c3516..c19cb92 100644 --- a/rpc-core/src/main/java/top/guoziyang/rpc/server/WorkerThread.java +++ b/rpc-core/src/main/java/top/guoziyang/rpc/server/RequestHandler.java @@ -4,6 +4,7 @@ import org.slf4j.LoggerFactory; import top.guoziyang.rpc.entity.RpcRequest; import top.guoziyang.rpc.entity.RpcResponse; +import top.guoziyang.rpc.enumeration.ResponseCode; import java.io.IOException; import java.io.ObjectInputStream; @@ -16,14 +17,14 @@ * 实际进行过程调用的工作线程 * @author ziyang */ -public class WorkerThread implements Runnable { +public class RequestHandler implements Runnable { - private static final Logger logger = LoggerFactory.getLogger(WorkerThread.class); + private static final Logger logger = LoggerFactory.getLogger(RequestHandler.class); private Socket socket; private Object service; - public WorkerThread(Socket socket, Object service) { + public RequestHandler(Socket socket, Object service) { this.socket = socket; this.service = service; } @@ -33,13 +34,26 @@ public void run() { try (ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream()); ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream())) { RpcRequest rpcRequest = (RpcRequest) objectInputStream.readObject(); - Method method = service.getClass().getMethod(rpcRequest.getMethodName(), rpcRequest.getParamTypes()); - Object returnObject = method.invoke(service, rpcRequest.getParameters()); + Object returnObject = invokeMethod(rpcRequest); objectOutputStream.writeObject(RpcResponse.success(returnObject)); objectOutputStream.flush(); - } catch (IOException | ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + } catch (IOException | ClassNotFoundException | IllegalAccessException | InvocationTargetException e) { logger.error("调用或发送时有错误发生:", e); } } + private Object invokeMethod(RpcRequest rpcRequest) throws IllegalAccessException, InvocationTargetException, ClassNotFoundException { + Class clazz = Class.forName(rpcRequest.getInterfaceName()); + if(!clazz.isAssignableFrom(service.getClass())) { + return RpcResponse.fail(ResponseCode.CLASS_NOT_FOUND); + } + Method method; + try { + method = service.getClass().getMethod(rpcRequest.getMethodName(), rpcRequest.getParamTypes()); + } catch (NoSuchMethodException e) { + return RpcResponse.fail(ResponseCode.METHOD_NOT_FOUND); + } + return method.invoke(service, rpcRequest.getParameters()); + } + } diff --git a/rpc-core/src/main/java/top/guoziyang/rpc/server/RpcServer.java b/rpc-core/src/main/java/top/guoziyang/rpc/server/RpcServer.java index 8e7e4e1..c19c6ef 100644 --- a/rpc-core/src/main/java/top/guoziyang/rpc/server/RpcServer.java +++ b/rpc-core/src/main/java/top/guoziyang/rpc/server/RpcServer.java @@ -31,8 +31,8 @@ public void register(Object service, int port) { logger.info("服务器正在启动..."); Socket socket; while((socket = serverSocket.accept()) != null) { - logger.info("客户端连接!Ip为:" + socket.getInetAddress()); - threadPool.execute(new WorkerThread(socket, service)); + logger.info("客户端连接!Ip为:" + socket.getInetAddress() + ":" + socket.getPort()); + threadPool.execute(new RequestHandler(socket, service)); } } catch (IOException e) { logger.error("连接时有错误发生:", e); diff --git a/test-server/src/main/java/top/guoziyang/test/HelloServiceImpl.java b/test-server/src/main/java/top/guoziyang/test/HelloServiceImpl.java index ebe5b73..80e009d 100644 --- a/test-server/src/main/java/top/guoziyang/test/HelloServiceImpl.java +++ b/test-server/src/main/java/top/guoziyang/test/HelloServiceImpl.java @@ -15,7 +15,7 @@ public class HelloServiceImpl implements HelloService { @Override public String hello(HelloObject object) { logger.info("接收到:{}", object.getMessage()); - return "这是掉用的返回值,id=" + object.getId(); + return "这是调用的返回值,id=" + object.getId(); } }