package com.remote.service;
/**
* Created by 79782 on 2018/7/22.
*/
public interface HelloService {
public String sayHello(String name);
}
package com.remote.service;
/**
* Created by 79782 on 2018/7/22.
*/
public class HelloServiceImpl implements HelloService {
public String sayHello(String name) {
return "hello:"+name;
}
}
package com.remote.server;
/**
* Created by 79782 on 2018/7/22.
*/
public interface Server {
public void start();
public void stop();
public void register(Class server ,Class serviceImpl);
}
package com.remote.server;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Method;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Created by 79782 on 2018/7/22.
*/
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 static void setPort(int port) {
ServerCenter.port = port;
}
public void start() {
isRunning=true;
ServerSocket server=null;
try {
server=new ServerSocket();
server.bind(new InetSocketAddress(9999));
} catch (IOException e) {
e.printStackTrace();
}
while(true){
try {
//等待客戶端連接 接受客戶端連接及請求
Socket socket = server.accept();
executor.execute(new ServiceTask(socket));
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void stop() {
isRunning=false;
executor.shutdown();
}
public void register(Class server ,Class serviceImpl) {
serviceRegiser.put(server.getName(),serviceImpl);
}
private static class ServiceTask implements Runnable{
private Socket socket;
public ServiceTask() {
}
public ServiceTask(Socket socket) {
this.socket = socket;
}
public void run() {
ObjectInputStream ois=null;
ObjectOutputStream oos =null;
try {
//Object流有順序
ois= new ObjectInputStream(socket.getInputStream());
//因爲ObjectInputeStream對發送數據的數據嚴格要求,所以可以一個一個接受
String serviceName=ois.readUTF();
String methodName=ois.readUTF();
Class[] paramType= (Class[]) ois.readObject();
Object[] arguments= (Object[]) ois.readObject();
//根據請求找到請求的接口
Class serviceClass = serviceRegiser.get(serviceName);
Method method = serviceClass.getMethod(methodName, paramType);
Object result=method.invoke(serviceClass.newInstance(), arguments);
oos= new ObjectOutputStream(socket.getOutputStream());
oos.writeObject(result);
}catch (Exception e) {
e.printStackTrace();
}finally {
if(oos!=null){
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(ois!=null){
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
package com.remote.client;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.InetSocketAddress;
import java.net.Socket;
/**
* Created by 79782 on 2018/7/22.
*/
public class Client {
//獲取代表服務端接口的動態代理對象
//serviceName:客戶端向服務端請求的接口名
@SuppressWarnings("unchecked")
public static <T> T getRemoteProxyObj(final Class serviceInterface, final InetSocketAddress addr){
return (T)Proxy.newProxyInstance(serviceInterface.getClassLoader(), new Class<?>[]{serviceInterface}, new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
ObjectOutputStream oos=null;
ObjectInputStream ois=null;
try{
Socket socket=new Socket();
socket.connect(addr);
oos= new ObjectOutputStream(socket.getOutputStream());
//接口名、接口方法名、方法類型,方法參數、
oos.writeUTF(serviceInterface.getName());
oos.writeUTF(method.getName());
oos.writeObject(method.getParameterTypes());
oos.writeObject(args);
//等待服務端處理
//服務端處理返回結果
ois= new ObjectInputStream(socket.getInputStream());
return ois.readObject();
}catch (Exception e){
e.printStackTrace();
return null;
}finally {
if(ois!=null){
ois.close();
}
if(oos!=null){
oos.close();
}
}
}
});
}
}
package com.remote.server;
import com.remote.service.HelloService;
import com.remote.service.HelloServiceImpl;
/**
* Created by 79782 on 2018/7/22.
*/
public class ServerMain {
/**
服務端將可以提供的接口註冊到服務中心 通過map保存key:發佈接口的名字,value:接口的實現類
服務端接收客戶端請求後,通過請求的接口名在服務中心的map中尋找對應的接口實現類。
解析客戶端發送的方法名,接口名,解析完畢後通過反射技術將該方法執行
執行完畢後將結果返回給客戶端
*/
public static void main(String[] args) {
new Thread(new Runnable() {
public void run() {
Server server=new ServerCenter();
server.register(HelloService.class, HelloServiceImpl.class);
server.start();
}
}).start();
}
}
package com.remote.client;
import com.remote.service.HelloService;
import java.net.InetSocketAddress;
/**
* Created by 79782 on 2018/7/22.
*/
public class ClientMain {
public static void main(String[] args) throws ClassNotFoundException {
/**
* 客戶端通過socket請求服務端,並且通過字符串形式將請求的接口名發送給服務端
* 動態代理:發送接口名,方法參數
*/
HelloService helloService=Client.getRemoteProxyObj(
Class.forName("com.remote.service.HelloService"),
new InetSocketAddress("127.0.0.1",9999));
System.out.println(helloService.sayHello("yanfang"));
}
}