获取Thrift调用的客户端IP地址的两种方式

thrift依赖

<dependency>
    <groupId>org.apache.thrift</groupId>
    <artifactId>libthrift</artifactId>
    <version>0.9.3</version>
</dependency>

简单接口

IDL

namespace java com.pp.calc
service Calculator{
    i32 add(1:i32 num1, 2:i32 num2)
    i64 multi(1:i32 num1, 2:i32 num2)
}

接口实现

package com.pp.calc.impl;

import org.apache.thrift.TException;

import com.pp.calc.Calculator;

public class CalculatorImpl implements Calculator.Iface
{
    public int add(int num1, int num2) throws TException
    {
        return num1 + num2;
    }

    public long multi(int num1, int num2) throws TException
    {
        return Long.valueOf(num1 * num2);
    }
}

方法一:使用事件监听的方式

package com.lala.server;

import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.protocol.TProtocolFactory;
import org.apache.thrift.server.ServerContext;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TServerEventHandler;
import org.apache.thrift.server.TThreadPoolServer;
import org.apache.thrift.transport.TServerSocket;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;

import com.pp.calc.Calculator;
import com.pp.calc.impl.CalculatorImpl;

/**
 * 使用事件监听的方式
 */
public class Server
{
    public static final int PORT = 9988;

    public static void main(String[] args)throws Exception
    {
        TServerSocket serverSocket = new TServerSocket(PORT);

        TProtocolFactory protocolFactory = new TCompactProtocol.Factory();

        TProcessor processor = new Calculator.Processor<>(new CalculatorImpl());

        final TServer server = new TThreadPoolServer(new TThreadPoolServer.Args(serverSocket).protocolFactory(protocolFactory).processor(processor));
        server.setServerEventHandler(new MyTServerEventHandler());

        server.serve();
    }
}

class MyTServerEventHandler implements TServerEventHandler
{
    /**
     * 服务成功启动后执行
     */
    public void preServe()
    {
        System.out.println("Start server on port " + Server.PORT + " ...");
    }

    /**
     * 创建Context的时候,触发
     * 在server启动后,只会执行一次
     */
    public ServerContext createContext(TProtocol input, TProtocol output)
    {
        System.out.println("createContext ... ");
        return null;
    }

    /**
     * 删除Context的时候,触发
     * 在server启动后,只会执行一次
     */
    public void deleteContext(ServerContext serverContext, TProtocol input, TProtocol output)
    {
        System.out.println("deleteContext ... ");
    }

    /**
     * 调用RPC服务的时候触发
     * 每调用一次方法,就会触发一次
     */
    public void processContext(ServerContext serverContext, TTransport inputTransport, TTransport outputTransport)
    {
        /**
         * 把TTransport对象转换成TSocket,然后在TSocket里面获取Socket,就可以拿到客户端IP
         */
        TSocket socket = (TSocket)inputTransport;
        System.out.println(socket.getSocket().getRemoteSocketAddress());

        System.out.println("method invoke ... ");
    }
}

方法二:使用代理的TProcessor

package com.lala.server;

import org.apache.thrift.TException;
import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.protocol.TProtocolFactory;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TThreadPoolServer;
import org.apache.thrift.transport.TServerSocket;
import org.apache.thrift.transport.TSocket;

import com.pp.calc.Calculator;
import com.pp.calc.impl.CalculatorImpl;

/**
 * 使用代理的TProcessor,获取客户端IP
 */
public class Server2
{
    public static final int PORT = 9988;

    public static void main(String[] args)throws Exception
    {
        TServerSocket serverSocket = new TServerSocket(PORT);

        TProtocolFactory protocolFactory = new TCompactProtocol.Factory();

        //注意这里,把真实的processor包装成LogProcessor
        TProcessor processor = new LogProcessor(new Calculator.Processor<>(new CalculatorImpl()));

        final TServer server = new TThreadPoolServer(new TThreadPoolServer.Args(serverSocket).protocolFactory(protocolFactory).processor(processor));

        server.serve();
    }
}

/**
 * 代理对象
 */
class LogProcessor implements TProcessor
{
    private TProcessor processor;

    public LogProcessor(TProcessor processor)
    {
        this.processor = processor;
    }

    /**
     * 该方法,客户端每调用一次,就会触发一次
     */
    public boolean process(TProtocol in, TProtocol out) throws TException
    {
        /**
         * 从TProtocol里面获取TTransport对象
         * 把TTransport对象转换成TSocket,然后在TSocket里面获取Socket,就可以拿到客户端IP
         */
        TSocket socket = (TSocket)in.getTransport();
        System.out.println(socket.getSocket().getRemoteSocketAddress());

        return processor.process(in, out);
    }
}
如果觉得这对你有用,请随意赞赏,给与作者支持
评论 0
最新评论