1. 程式人生 > >利用Thrift使Java與C#進行通訊

利用Thrift使Java與C#進行通訊

struct UserProfile{  
        1:i32 id, 
        2:string name,  
        3:string blurb  
}   
service UserStorage{  
        void store(1: UserProfile user),   
        UserProfile getUser(1: i32 uid)  
} 

若傳輸檔案,建立Interface.thrift檔案,內容如下:

struct FileData  
{  
    1:required string   name,                   // 檔名字  
2:required binary buff, // 檔案資料 }

Service

service FileInfoExtractService  
{  
    bool uploadFile(1:FileData filedata);       // 檔案解析函式  
} 

步驟4. 開啟doc視窗,進入thrift所在的目錄,輸入thrift-0.11.0.exe -r -gen java(或csharp) domo.thrift。資料夾中自動生成一個名字為gen-java(或gen-csharp)的資料夾,下面就是生成的java(或csharp)檔案。 步驟5.

客戶端: C#客戶端:thrift-0.11.0\lib\csharp\src\Thrift.sln 編譯,即可生成Thrift.dll檔案,要在C#客戶端專案中依賴該檔案。步驟4中生成的.cs檔案加入到專案中。 資料傳輸時ClientApp.cs檔案寫法:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Thrift.Transport;
using Thrift.Protocol;

namespace ThriftTest
{
    class ClientApp
{
static void Main(string[] args) { TTransport transport = new TSocket("localhost", 8899); TProtocol protocol = new TBinaryProtocol(transport); test.Hello.Client client = new test.Hello.Client(protocol); transport.Open(); Console.WriteLine("Client calls client.helloString()....."); Console.WriteLine(client.helloString("jiyiqin")); client.Dispose(); } } }

檔案傳輸時,ClientApp .cs檔案寫法:

using System;
using Thrift.Transport;
using Thrift.Protocol;
using System.IO;

class ClientApp 
{
    static void Main(string[] args)
    {
         String filePath = "D://fruit.jpg";
        FileData fileData = new FileData();
        byte[] bytes = set(filePath);
        fileData.Name = filePath;
        fileData.Buff = bytes;
        try
        {
            TSocket transport = new TSocket("localhost", 12345);
            TFramedTransport framedTransport = new TFramedTransport(transport);
            Console.WriteLine("fdsfs");
            framedTransport.Open();
            TBinaryProtocol binaryProtocol = new TBinaryProtocol(framedTransport);
            FileService.Client client = new FileService.Client(binaryProtocol);
            client.uploadFile(fileData);
        }
        catch (Exception x)
        {
            Console.WriteLine("錯了");
        }
        Console.ReadLine();
    }
private static byte[] set(String filePath)     //建立set函式
{
    FileInfo fileInfo = new FileInfo(filePath);
    byte[] b = new byte[fileInfo.Length];
    FileStream fs = new FileStream(filePath,FileMode.Open,FileAccess.Read);
    fs.Read(b,0,b.Length);
    fs.Close();
    GC.ReRegisterForFinalize(fileInfo);
    GC.ReRegisterForFinalize(fs);
    return b;
}

}`

java客戶端:thrift-0.11.0\lib\java(包含build.xml),通過ant命令生成jar檔案,新建專案,匯入libthrift-0.11.0.jar 資料傳輸時ClientApp .java檔案寫法:

import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TTransportException;
public class ClientApp {
    public static final String SERVER_IP = "localhost";
    public static final int SERVER_PORT = 8899;
    public static final int TIMEOUT = 30000;
    public static void main(String[] args) {
        Client client = new Client();
        client.startClient("amosli");
    }
    public void startClient(String userName) {
        userName ="jiaqian";
        TTransport transport = null;
        String result = null;
        try {
            transport = new TSocket(SERVER_IP, SERVER_PORT, TIMEOUT);
            // 協議要和服務端一致
            TProtocol protocol = new TBinaryProtocol(transport);
            // TProtocol protocol = new TJSONProtocol(transport);
            Hello.Client client = new Hello.Client(protocol);
            transport.open();
            result = client.helloString(userName);
            System.out.println("Thrift client result =: " + result);
        } 
catch (TTransportException e) {
            e.printStackTrace();
        } catch (TException e) {
            e.printStackTrace();
        } finally {
            if (null != transport) {
                transport.close();
            }
        }
    }
}

檔案傳輸時ClientApp.java檔案寫法:

import org.apache.thrift.protocol.TBinaryProtocol;  
import org.apache.thrift.transport.TFramedTransport;  
import org.apache.thrift.transport.TSocket;  
import java.io.ByteArrayOutputStream;  
import java.io.File;  
import java.io.FileInputStream;  
import java.nio.ByteBuffer;  
public class ClientApp
{  
    public static void main(String[] args)  
    {  
        // 測試檔案路徑  
        String filePath = "D:\\fruit.jpg";  
        // 構造檔案資料  
        byte[] bytes = toByteArray(filePath);  
        FileData fileData = new FileData();  
        fileData.name = filePath;  
        fileData.buff = ByteBuffer.wrap(bytes);  
        // 構造Thrift客戶端,發起請求  
        try  
        {  
            TSocket socket = new TSocket("localhost", 12345);  
            socket.setSocketTimeout(60 * 1000);  
            TFramedTransport framedTransport = new TFramedTransport(socket);  
            framedTransport.open();  
            TBinaryProtocol binaryProtocol = new TBinaryProtocol(framedTransport);  
            FileService.Client client = new FileService.Client(binaryProtocol);  
            client.uploadFile(fileData);  
        }  
        catch (Exception x)  
        {  
            x.printStackTrace();  
        }
    }  
    /** 
     * 檔案轉化為位元組陣列 
     * */  
    private static byte[] toByteArray(String filePath){  
        byte[] buffer = null;  
        try {  
            File file = new File(filePath);  
            FileInputStream fis = new FileInputStream(file);  
            ByteArrayOutputStream bos = new ByteArrayOutputStream(1000);  
            byte[] b = new byte[1000];  
            int n;  
            while ((n = fis.read(b)) != -1) {  
                bos.write(b, 0, n);  
            }  
            fis.close();  
            bos.close();  
            buffer = bos.toByteArray();  
        } catch (Exception e) {  
            e.printStackTrace();  
        }
        return buffer;  
    }  
}  

步驟6. java服務端: 傳輸資料時ServiceApp.java檔案寫法:

import org.apache.thrift.protocol.TBinaryProtocol;     
import org.apache.thrift.protocol.TBinaryProtocol.Factory;     
import org.apache.thrift.server.TServer;     
import org.apache.thrift.server.TThreadPoolServer;     
import org.apache.thrift.server.TThreadPoolServer.Args;     
import org.apache.thrift.transport.TServerSocket;     
import org.apache.thrift.transport.TTransportException;
import com.jiaqian.thirft.Hello.Processor;   
public class ServiceApp {   
   @SuppressWarnings({"rawtypes", "unchecked" })  
    public String startServer() {     
        try {     
            System.out.println("thrift server host on port 8899");   
            TServerSocket serverTransport = new TServerSocket(8899);  
            Hello.Processor process = new Processor(new HelloImpl());     
            Factory portFactory = new TBinaryProtocol.Factory(true, true);     
            Args args = new Args(serverTransport);     
            args.processor(process);
            args.protocolFactory(portFactory);     
            TServer server = new TThreadPoolServer(args);     
            server.serve();   
        } catch (TTransportException e) {
            e.printStackTrace();
        }
        return "thrift server host on port 8899";    
   }
   public static void main(String[] args) {      
        System.out.println("thrift server init");   
        Server server = new Server();
        System.out.println("thrift server start");   
        server.startServer();     
        System.out.println("thrift server end");   
   }     
}   

傳輸資料時HelloImp.java寫法:

import org.apache.thrift.TException;
import com.jiaqian.thirft.Hello.Iface;  

public class HelloImpl implements Iface{   
   private static int count= 0;        
   @Override   
   public String helloString(String word)throws TException  
   {  
        count += 1;   
        System.out.println("get " + word + " " +count);    
        return "hello " + word + " " + count;   
   }    
}  

傳輸檔案時ServiceApp.java檔案寫法

import org.apache.thrift.TProcessor;  
import org.apache.thrift.protocol.TBinaryProtocol;  
import org.apache.thrift.server.TServer;  
import org.apache.thrift.server.TThreadedSelectorServer;  
import org.apache.thrift.transport.TFramedTransport;  
import org.apache.thrift.transport.TNonblockingServerSocket;  
import org.apache.thrift.transport.TNonblockingServerTransport;  
import org.apache.thrift.transport.TTransportFactory;  

public class ServiceApp
{  
    public static void main(String[] args)  
    {  
        try  
        {  
            // 建立非阻塞的 Transport  
            TNonblockingServerTransport serverSocket = new TNonblockingServerSocket(12345);  
            // 建立 Processor  
            TProcessor processor = new FileService.Processor(new FileServiceImpl());  
            // 建立 transport factory , Nonblocking 使用 TFramedTransport  
            TTransportFactory transportFactory = new TFramedTransport.Factory();  
            // 建立 protocol factory  
            TBinaryProtocol.Factory protocolFactory = new TBinaryProtocol.Factory();  
            // 建立 arguments  
            TThreadedSelectorServer.Args tArgs = new TThreadedSelectorServer.Args(serverSocket);  
            tArgs.processor(processor);  
            tArgs.transportFactory(transportFactory);  
            tArgs.protocolFactory(protocolFactory);  
            // 建立 server  
            TServer server = new TThreadedSelectorServer(tArgs);  
            // 啟動 server  
            server.serve();  
        }  
        catch (Exception x)  
        {  
            x.printStackTrace();  
        }  
    }  
}  

傳檔案時java的FileServiceImpl.java檔案寫法:

import org.apache.thrift.TException;
import java.io.FileOutputStream;  
import java.nio.channels.FileChannel;  
public class FileServiceImpl implements FileService.Iface  
{  
    int i=1;
    @Override  
    public boolean uploadFile(FileData filedata) throws TException  
    {  
        System.out.println("uploadFile function has been called.");  
        i++;
        // 寫到檔案  
        String filePath = "D:\\fruit"+i+".jpg";  
        try  
        {  
            java.io.File file = new java.io.File(filePath);  
            FileOutputStream fos = new FileOutputStream(file);  
            FileChannel channel = fos.getChannel();  
            channel.write(filedata.buff);  
            channel.close();  
        }  
        catch (Exception x)  
        {  
            x.printStackTrace();  
            return false;  
        }  
        return true;  
    }  
}