RPC实现

1.目录整体结构如下
在这里插入图片描述
1.服务端定义接口为HelloService

package cn.rpc.demo.service;

/**
 * @author insulators
 * @date 2019/5/27 14:29
 **/
public interface HelloService {
    public void sayHello(String  info);
}

2.在服务端实现helloService

package cn.rpc.demo.service.impl;


import cn.rpc.demo.service.HelloService;

/**
 * @author insulators
 * @date 2019/5/27 14:29
 **/
public class HelloServiceImpl implements HelloService {
    @Override
    public void sayHello(String info) {
        System.out.println("Hello"+info);
    }
}

3.在服务端rpc服务端

package org.rpc.server;

import com.google.common.collect.Maps;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author insulators
 * @date 2019/5/27 14:29
 **/
public class RpcServer {

    private ConcurrentMap<Object, Object> severList = Maps.newConcurrentMap();
    private ThreadPoolExecutor pol = new ThreadPoolExecutor(8, 30, 1000, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(10));

    public void start(int port) throws IOException {
        ServerSocket serverSocket = new ServerSocket(port);
        Socket socket = serverSocket.accept();
        System.out.println("==================服务启动成功==================");
        //执行线程任务
        pol.execute(new ServerTask(socket));

    }
    
    //发布接口服务
    public void publisherServer(Class<?> clz, Class<?> clzImpl) throws IllegalAccessException, InstantiationException {
        System.out.println("==================接口发布成功==================");
        severList.put(clz.getName(), clzImpl.newInstance());
    }
    
    //线程任务
    private class ServerTask implements Runnable {
        private final Socket socket;

        private ServerTask(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            try (ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
                 ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());) {
                String serviceName = input.readUTF();
                String methodName = input.readUTF();
                Class<?>[] paramType = (Class<?>[]) input.readObject();
                Object[] params = (Object[]) input.readObject();
                Object instance = severList.get(serviceName);
                if (instance == null) {
                    System.out.println("服务不存在");
                }
                Method method = instance.getClass().getDeclaredMethod(methodName, paramType);
                if (method == null) {
                    System.out.println("方法不存在");
                    return;
                }
                output.writeObject(method.invoke(instance, params));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

4.在客户端引入HelloService接口
在这里插入图片描述
5.在客户端实现调用

package org.rpc.client;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.Socket;

/**
 * @author insulators
 * @date 2019/5/27 14:29
 **/
public class RpcClient {
    public <T> T proxyClient(final Class<?> clazz, final int port) {

        return (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class<?>[]{clazz}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Socket socket = new Socket("localhost", port);
                try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
                     ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
                ) {
                    objectOutputStream.writeUTF(clazz.getName());
                    objectOutputStream.writeUTF(method.getName());
                    objectOutputStream.writeObject(method.getParameterTypes());
                    objectOutputStream.writeObject(args);
                    return objectInputStream.readObject();
                } catch (Exception e) {
                    e.printStackTrace();
                }

                return null;
            }
        });

    }
}

6.启动服务端发布服务

package cn.rpc.demo;

import cn.rpc.demo.service.HelloService;
import cn.rpc.demo.service.impl.HelloServiceImpl;
import org.rpc.server.RpcServer;

import java.io.IOException;

/**
 * @author  insulators
 * @date 2019/5/27 14:29
 **/
public class App 
{
    public static void main( String[] args ) throws IOException, InstantiationException, IllegalAccessException {
        RpcServer rpcServer = new RpcServer();
        rpcServer.publisherServer(HelloService.class, HelloServiceImpl.class);
        rpcServer.start(8000);
    }
}

7.启动客户端调用服务

public class App 
{
    public static void main( String[] args ) {
        RpcClient rpcClient = new RpcClient();
        HelloService helloService = rpcClient.proxyClient(HelloService.class, 8000);
        helloService.sayHello("测试rpc服务调用");
    }
}

8.结果
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值