Maybe it was the birthday hangover, maybe it was the fact that it was 2am, but I couldn't find a working "Hello World" for Thrift 0.9.0.
What I was trying to do, point-form styles:
- Run a java server with my business logic
- Interface with that fella in PHP
After some reading, I figured Thrift was definitely worth looking into.
Hopefully this save a few people some cranky moments!
Hopefully this save a few people some cranky moments!
Step 1: download thrift.
This link should do the trick if you don't feel like compiling anything:
https://dist.apache.org/repos/dist/release/thrift/0.9.0/thrift-0.9.0.exe
Step 2: write your thrift file.
Mine looked like this.
1: # time.thrift
2: namespace java com.myFirstServer.thrift
3: typedef i64 Timestamp
4: service TimeServer {
5: Timestamp time()
6: }
Step 3: generate the PHP client code
> thrift --gen php src\main\resources\server.thrift
You'll end up with two files in this case:
- TimeServer.php
- Types.php
Step 4: generate the Java server code
> thrift --gen java server.thrift
This will have generated
- TimeServer.java
Essentially, this is where you code your implementation of the thrift file we wrote earlier.
1: package com.myFirstServer.thrift;
2: import java.util.Date;
3: import org.apache.thrift.TException;
4: public class TimeServerImpl implements TimeServer.Iface
5: {
6: @Override
7: public long time() throws TException
8: {
9: return new Date().getTime();
10: }
11: }
Step 5A: make sure you have your Maven dependencies setup:
<dependency>
<groupId>org.apache.thrift</groupId>
<artifactId>libthrift</artifactId>
<version>0.9.0</version>
</dependency>
Step 6: write your server's "main"
1: package com.myFirstServer.server;
2: import org.apache.thrift.server.TServer;
3: import org.apache.thrift.server.TThreadPoolServer;
4: import org.apache.thrift.transport.TServerSocket;
5: import org.apache.thrift.transport.TTransportException;
6: import com.myFirstServer.thrift.TimeServer;
7: import com.myFirstServer.thrift.TimeServerImpl;
8: public class PriceServer
9: {
10: private void start() {
11: try {
12: TServerSocket serverTransport = new TServerSocket(7911);
13: TimeServer.Processor processor = new TimeServer.Processor (new TimeServerImpl());
14: TServer server = new TThreadPoolServer(new TThreadPoolServer.Args(serverTransport).processor(processor));
15: System.out.println("Starting server on port 7911 ...");
16: server.serve();
17: }
18: catch (TTransportException e)
19: {
20: e.printStackTrace();
21: }
22: }
23: public static void main(String[] args) {
24: PriceServer srv = new PriceServer();
25: srv.start();
26: }
27: }
Easy-peazy.
Now begins the headache that was the PHP client side.
Seems that I starred at every permutation of these messages for the better part of an hour (I couldn't find a proper Thrift 0.9.0 tutorial... and it seem that things had changed enough to obsolete older tutorial):
[Tue Nov 06 15:01:57 2012] [error] [client 192.168.1.125] PHP Warning: require_once(TimeServerClient.php): failed to open stream: No such file or directory in /home/erik/samba_share/ThriftTest.php on line 6
[Tue Nov 06 15:01:57 2012] [error] [client 192.168.1.125] PHP Fatal error: require_once(): Failed opening required 'TimeServerClient.php' (include_path='.:/usr/share/php:/usr/share/pear') in /home/erik/samba_share/ThriftTest.php on line 6
Disclaimer: I'm very much a PHP newbie.
7. Download the Thrift PHP libs
Now, as opposed to what all the other tutorials tell you: you don't need to install, apt-get or build anything. All you need are the PHP libs that are packaged with Thrift, while trying to follow how-to's, I installed about a dozen dependencies on my linux machine for nothin'.
Let's say you end up untar-ing the bundle here "/home/erik/thrift-0.9.0", all you really care about will be "'/home/erik/thrift-0.9.0/lib/php/lib'".
Unless you insist on compiling the code generator, I don't feel you'll need anything BUT the PHP dependencies (which you will specify in the client code).
8. Write your client
I named it "ThriftTest.php"
1: <?php
2: $GLOBALS['THRIFT_ROOT'] = '/home/erik/thrift-0.9.0/lib/php/lib';
3: /* Remember these two files? */
4: require_once 'Types.php';
5: require_once 'TimeServer.php';
6: /* Dependencies. In the proper order. */
7: require_once $GLOBALS['THRIFT_ROOT'].'/Thrift/Transport/TTransport.php';
8: require_once $GLOBALS['THRIFT_ROOT'].'/Thrift/Transport/TSocket.php';
9: require_once $GLOBALS['THRIFT_ROOT'].'/Thrift/Protocol/TProtocol.php';
10: require_once $GLOBALS['THRIFT_ROOT'].'/Thrift/Protocol/TBinaryProtocol.php';
11: require_once $GLOBALS['THRIFT_ROOT'].'/Thrift/Transport/TBufferedTransport.php';
12: require_once $GLOBALS['THRIFT_ROOT'].'/Thrift/Type/TMessageType.php';
13: require_once $GLOBALS['THRIFT_ROOT'].'/Thrift/Factory/TStringFuncFactory.php';
14: require_once $GLOBALS['THRIFT_ROOT'].'/Thrift/StringFunc/TStringFunc.php';
15: require_once $GLOBALS['THRIFT_ROOT'].'/Thrift/StringFunc/Core.php';
16: require_once $GLOBALS['THRIFT_ROOT'].'/Thrift/Type/TType.php';
17: use Thrift\Protocol\TBinaryProtocol;
18: use Thrift\Transport\TSocket;
19: use Thrift\Transport\TSocketPool;
20: use Thrift\Transport\TFramedTransport;
21: use Thrift\Transport\TBufferedTransport;
22: $host = '192.168.1.125';
23: $port = 7911;
24: $socket = new Thrift\Transport\TSocket($host, $port);
25: $transport = new TBufferedTransport($socket);
26: $protocol = new TBinaryProtocol($transport);
27: // Create a calculator client
28: $client = new TimeServerClient($protocol);
29: $transport->open();
30: echo "Time: " . $client -> time();
31: ?>
And there you have it: launch the server...
Starting server on port 7911 ...
... and connect with your browser to your web server (http://192.168.1.199/ThriftTest.php)
Mission accomplished!
-Erik
Thank you to the following tutorials for getting me most of the way there:
http://nbonvin.wordpress.com/2009/03/08/simple-thrift-tutorial/
http://saladwithsteve.com/2008/04/my-first-thrift-app.html