<NME> ExampleServiceImpl.java
<BEF> package com.github.wenweihu86.raft.example.server.service.impl;

import com.github.wenweihu86.raft.example.server.ExampleStateMachine;
import com.github.wenweihu86.raft.example.server.service.Example;
import com.github.wenweihu86.raft.example.server.service.ExampleService;
import com.github.wenweihu86.raft.RaftNode;
import com.github.wenweihu86.raft.proto.Raft;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.util.JsonFormat;
import org.slf4j.Logger;
import com.googlecode.protobuf.format.JsonFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by wenweihu86 on 2017/5/9.
 */
public class ExampleServiceImpl implements ExampleService {

    private static final Logger LOG = LoggerFactory.getLogger(ExampleServiceImpl.class);
    private static JsonFormat jsonFormat = new JsonFormat();

    private RaftNode raftNode;
    }

    @Override
    public Example.SetResponse set(Example.SetRequest request) {
        byte[] data = request.toByteArray();
        // 数据同步写入raft集群
        boolean success = raftNode.replicate(data, Raft.EntryType.ENTRY_TYPE_DATA);
        Example.SetResponse response = Example.SetResponse.newBuilder()
                .setSuccess(success).build();
        try {
            LOG.info("set request, request={}, response={}", printer.print(request),
                    printer.print(response));
        } catch (InvalidProtocolBufferException ex) {
            ex.printStackTrace();
        }

        return response;
    }

    @Override
    public Example.GetResponse get(Example.GetRequest request) {
        Example.GetResponse response = stateMachine.get(request);
        try {
            LOG.info("get request, request={}, response={}", printer.print(request),
                    printer.print(response));
            responseBuilder.setSuccess(false);
        } else if (raftNode.getLeaderId() != raftNode.getLocalServer().getServerId()) {
            onLeaderChangeEvent();
            ExampleService exampleService = BrpcProxy.getProxy(leaderRpcClient, ExampleService.class);
            ExampleProto.SetResponse responseFromLeader = exampleService.set(request);
            responseBuilder.mergeFrom(responseFromLeader);
        } else {
            // 数据同步写入raft集群
            byte[] data = request.toByteArray();
            boolean success = raftNode.replicate(data, RaftProto.EntryType.ENTRY_TYPE_DATA);
            responseBuilder.setSuccess(success);
        }

        ExampleProto.SetResponse response = responseBuilder.build();
        LOG.info("set request, request={}, response={}", jsonFormat.printToString(request),
                jsonFormat.printToString(response));
        return response;
    }

    @Override
    public ExampleProto.GetResponse get(ExampleProto.GetRequest request) {
        ExampleProto.GetResponse response = stateMachine.get(request);
        LOG.info("get request, request={}, response={}", jsonFormat.printToString(request),
                jsonFormat.printToString(response));
        return response;
    }

}

<MSG> 1. transfer set request to leader 2. rename proto to RaftMessage

<DFF> @@ -1,10 +1,12 @@
 package com.github.wenweihu86.raft.example.server.service.impl;
 
 import com.github.wenweihu86.raft.example.server.ExampleStateMachine;
-import com.github.wenweihu86.raft.example.server.service.Example;
+import com.github.wenweihu86.raft.example.server.service.ExampleMessage;
 import com.github.wenweihu86.raft.example.server.service.ExampleService;
 import com.github.wenweihu86.raft.RaftNode;
-import com.github.wenweihu86.raft.proto.Raft;
+import com.github.wenweihu86.raft.proto.RaftMessage;
+import com.github.wenweihu86.rpc.client.RPCClient;
+import com.github.wenweihu86.rpc.client.RPCProxy;
 import com.google.protobuf.InvalidProtocolBufferException;
 import com.google.protobuf.util.JsonFormat;
 import org.slf4j.Logger;
@@ -27,25 +29,36 @@ public class ExampleServiceImpl implements ExampleService {
     }
 
     @Override
-    public Example.SetResponse set(Example.SetRequest request) {
-        byte[] data = request.toByteArray();
-        // 数据同步写入raft集群
-        boolean success = raftNode.replicate(data, Raft.EntryType.ENTRY_TYPE_DATA);
-        Example.SetResponse response = Example.SetResponse.newBuilder()
-                .setSuccess(success).build();
+    public ExampleMessage.SetResponse set(ExampleMessage.SetRequest request) {
+        ExampleMessage.SetResponse.Builder responseBuilder = ExampleMessage.SetResponse.newBuilder();
+        // 如果自己不是leader，将写请求转发给leader
+        if (raftNode.getLeaderId() <= 0) {
+            responseBuilder.setSuccess(false);
+        } else if (raftNode.getLeaderId() != raftNode.getLocalServer().getServerId()) {
+            RPCClient rpcClient = raftNode.getPeerMap().get(raftNode.getLeaderId()).getRpcClient();
+            ExampleService exampleService = RPCProxy.getProxy(rpcClient, ExampleService.class);
+            ExampleMessage.SetResponse responseFromLeader = exampleService.set(request);
+            responseBuilder.mergeFrom(responseFromLeader);
+        } else {
+            // 数据同步写入raft集群
+            byte[] data = request.toByteArray();
+            boolean success = raftNode.replicate(data, RaftMessage.EntryType.ENTRY_TYPE_DATA);
+            responseBuilder.setSuccess(success);
+        }
+
+        ExampleMessage.SetResponse response = responseBuilder.build();
         try {
             LOG.info("set request, request={}, response={}", printer.print(request),
                     printer.print(response));
         } catch (InvalidProtocolBufferException ex) {
             ex.printStackTrace();
         }
-
         return response;
     }
 
     @Override
-    public Example.GetResponse get(Example.GetRequest request) {
-        Example.GetResponse response = stateMachine.get(request);
+    public ExampleMessage.GetResponse get(ExampleMessage.GetRequest request) {
+        ExampleMessage.GetResponse response = stateMachine.get(request);
         try {
             LOG.info("get request, request={}, response={}", printer.print(request),
                     printer.print(response));

1. transfer set request to leader 2. rename proto to RaftMessage