Sheppard Y

keep thinking keep coding.

PHP/Java Bridge的使用

2016-07-06 日更新 
此篇博客已经迁移到新博客,并做行文检查和优化排版:
http://blog.clawz.me/2013/01/18/13-php-java-bridge/

 


一、需求背景

    之前介绍过我们项目的架构,由于历史原因,架构演变成as<-->java<-->php这样,java与as通过tcp长连接通信,java与php通过两条http通道来通信(java与php各自有个http server,并各自作为对方的http client,java转发as以前的post给php;php需要跨session推送或者广播时变为http client向java的http server做post)。

    这之前的架构是as的功能逻辑大部分直接与php进行http通信。

    项目的目标是慢慢将php部分写的糟糕的已有逻辑(例如帮派这种交互和广播同步比较多的)改到java服务器上。项目人员配备跟不上,所以不能一下子全转了。

    如果用之前的两条http通道来小步快跑式的移逻辑,就需要再封装这两个通道之间的通信,费时间还不一定好使,所以我们需要一个java直接调用php的技术。

    goole了解后,最终决定使用PHP/Java Bridge。 

 

二、PHP/Java Bridge

(一)示例

CallPhp.java

 1 package me.sheppardy.study;
 2 
 3 import java.io.ByteArrayOutputStream;
 4 import java.io.FileReader;
 5 
 6 import javax.script.ScriptEngine;
 7 import javax.script.ScriptEngineManager;
 8 
 9 /**
10  * 
11  * PHP/Java Bridge, example
12  * @author sheppard(ysf1026@gmail.com) 2013-01-18
13  *
14  */
15 public class CallPhp
16 {
17         
18         public static void main(String[] args) throws Exception
19         {
20                 test(1104);
21                 test(531);
22                 test(1221);
23                 test(110);
24         }
25         
26         public static void test(int id) throws Exception
27         {
28                 Response rep = new Response();
29                 call(new Request(id), rep);
30                 System.out.println("CallPhp.test, id=" + id + " message=" + rep.message);
31         }
32         
33         public static void call(Request req, Response rep) throws Exception
34         {
35                 ScriptEngineManager engineManager = new ScriptEngineManager();
36                 ScriptEngine engine = engineManager.getEngineByName("php-invocable");
37 
38                 ByteArrayOutputStream log = new ByteArrayOutputStream();
39 
40                 try
41                 {
42                         engine.put("phpRootDir", "data/php");
43                         engine.put("log", log);
44                         engine.put("req", req);
45                         engine.put("rep", rep);
46                         FileReader reader = new FileReader("data/php/gate.php");
47                         engine.eval(reader);
48                         System.out.println("CallPhp.call phpLog=" + log.toString());
49                 }
50                 catch(Exception e)
51                 {
52                         System.out.println("CallPhp.call phpLog=" + log.toString());
53                         throw e;
54                 }
55         }
56 }
57 
58 class Request
59 {
60         public Request(int id)
61         {
62                 this.id = id;
63         }
64         public int id;
65 }
66 
67 class Response
68 {
69         public String message;
70 }

java-bin/data/php/gate.php

 1 <?php
 2 
 3 /**
 4  *
 5  * 脚本统一入口
 6  * @author sheppard(ysf1026@gmail.com) 2013-01-18
 7  *
 8  */
 9 
10 define('PHP_ROOT_DIR', java_context()->get('phpRootDir'));
11 $log = java_context()->get('log');
12 $log->write("\n\tjava give phpRootDir is " . PHP_ROOT_DIR);
13 
14 require_once(PHP_ROOT_DIR . '/function.php');
15 
16 $log->write(getDoomsday());
17 
18 $rep = java_context()->get('rep');
19 $rep->message = handle(java_context()->get('req'), $log);
20 
21 ?>

 

java-bin/data/php/function.php

 1 <?php
 2 
 3 /**
 4  *
 5  * 具体功能举例
 6  * @author sheppard(ysf1026@gmail.com) 2013-01-18
 7  *
 8  */
 9 
10 function getDoomsday()
11 {
12         return "\n\tdoomsday is 20121221";      
13 }
14 
15 function handle($req$log)
16 {
17         $id = $req->id;
18         $log->write("\n\tfunction.php handle id=$id");
19         if('1104' == $id)
20                 return 'guess?';
21         else if('531' == $id)
22                 return 'score';
23         else if('1221' == $id)
24                 return 'maybe doomsday';
25         else
26                 return '404 not found';
27 }
28 
29 ?>

 

output

 1 CallPhp.call phpLog=
 2 java give phpRootDir is data/php
 3 doomsday is 20121221
 4 function.php handle id=1104
 5 CallPhp.test, id=1104 message=guess?
 6 CallPhp.call phpLog=
 7 java give phpRootDir is data/php
 8 doomsday is 20121221
 9 function.php handle id=531
10 CallPhp.test, id=531 message=score
11 CallPhp.call phpLog=
12 java give phpRootDir is data/php
13 doomsday is 20121221
14 function.php handle id=1221
15 CallPhp.test, id=1221 message=maybe doomsday
16 CallPhp.call phpLog=
17 java give phpRootDir is data/php
18 doomsday is 20121221
19 function.php handle id=110
20 CallPhp.test, id=110 message=404 not found

 

(二)注意事项

1. 由于是java调用的php,所以php里当前工作路径变成了java的。

2. FileReader加载*.php文件之后ScriptEngine.evel(FileReader)的耗时大概为230+ms,StringReader时为180+ms,速度都不咋滴,但是这不是我们项目急着考虑的问题,之前的http方式也好不到哪去,优化留到以后再说。

3. php的解释器运行路径配置:-Dphp.java.bridge.php_exec=。

 

三、相关资料

1. 官网:http://php-java-bridge.sourceforge.net/pjb/

2. 符合java调脚本标准的调php示例:http://php-java-bridge.sourceforge.net/pjb/examples/source.php?source=PhpThreads.java


ps:2013年1月18日我在CU的博客

 

 

 

 

posted on 2013-04-08 18:20 Sheppard Y 阅读(828) 评论(0)  编辑 收藏 引用 所属分类: 其他语言设计架构


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2013年10月>
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

导航

统计

留言簿(1)

随笔分类(77)

随笔档案(58)

me

基友

同行

业界前辈

最新随笔

搜索

积分与排名

最新评论

阅读排行榜