phprpc初步

官网:

http://phprpc.org/

java只有源代码,不过包含了个make.bat运行后就生成了三个jar包,服务端只需要phprpc.jar,客户端需要phprpc_client.jar,不需要别的依赖包,very nice,那个phprpc_spring.jar的包尚不知是做什么用的。

服务端,自定义接口:

package kzg.phprpc.hello.api;

public interface Hello
{
	String hello(String msg);
	Cdata getData1();
}

自定义Cdata类(要实现Serializable接口):

package kzg.phprpc.hello.api;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Cdata implements Serializable
{
	private static final long serialVersionUID = 1L;
	private String s1;
	private int s2;
	private List ss = new ArrayList();
	private Map map = new HashMap();

	public Cdata(String arg)
	{
		map.put("m1", "m1v");
		ss.add("l1");
		s1 = arg;
		s2 = 12;
	}

	public String getS1()
	{
		return s1;
	}

	public int getS2()
	{
		return s2;
	}

	public List getSs()
	{
		return ss;
	}

	public Map getMap()
	{
		return map;
	}
}

发布rpc的filter(servlet都可以):

package kzg.phprpc.hello.service;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.phprpc.PHPRPC_Server;

public class RpcService implements Filter
{

	public void destroy()
	{

	}

	public void doFilter(ServletRequest arequest, ServletResponse aresponse, FilterChain chain) throws IOException,
		ServletException
	{
		HttpServletRequest request = (HttpServletRequest) arequest;
		HttpServletResponse response = (HttpServletResponse) aresponse;

		PHPRPC_Server phprpc_server = new PHPRPC_Server();
		phprpc_server.add(new HelloImpl());
		phprpc_server.start(request, response);
	}

	public void init(FilterConfig filterConfig) throws ServletException
	{

	}

}

注意,这里将helloimpl整个类的public方法都发布了,如果是使用javascript,则根本就不需要接口申明,但是对于Java客户端,还是写个接口便于操作。

配置web.xml:

       <filter>
		<filter-name>rpcFilter</filter-name>
		<filter-class>kzg.phprpc.hello.service.RpcService</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>rpcFilter</filter-name>
		<url-pattern>/phprpc/</url-pattern>
	</filter-mapping>

 

java客户端代码:

package kzg.phprpc.hello.client;

import kzg.phprpc.hello.api.Cdata;
import kzg.phprpc.hello.api.Hello;

import org.phprpc.PHPRPC_Client;

public class HelloClient
{
	public static void main(String[] args)
	{
		PHPRPC_Client client = new PHPRPC_Client("http://localhost:10010/phprpc-test/phprpc/");
		client.setKeyLength(512);
		client.setEncryptMode(1);
		Hello api = (Hello) client.useService(Hello.class);
		Cdata data = api.getData1();
		System.out.println("call---->" + api.hello("hi."));
		System.out.println("string:" + data.getS1());
		System.out.println("int:" + data.getS2());
		System.out.println("array:" + data.getSs());
		System.out.println("map:" + data.getMap());
	}
}

 

javascript客户端代码:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>test.html</title>
	
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="this is my page">
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    
    <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->
	<script type="text/javascript" src="js/phprpc_client.js"></script>
	<script type="text/javascript">
		var client = new PHPRPC_Client('http://localhost:10010/phprpc-test/phprpc/', ['hello', 'getData1']);  
		client.setKeyLength(256);  
		client.setEncryptMode(2);	
		client.hello('你好',function (result, args, output, warning) {  
		    alert(result); 
		});	  
		client.getData1(function (result, args, output, warning) {  
		    console.log(result);
		    alert(result.map['m1']); 
		});
	</script>
  </head>
  
  <body>
    
  </body>
</html>

返回的将Cdata转为了json对象。

phprpc_client.js这个脚本才18k,gzip压缩后才9k,非常小。

这里我故意使用中文测试了一下编码问题,运行得很好,由于PHPRPC默认使用UTF-8 字符集,我的html编码也是utf-8,这样就不需要什么额外处理,非常不错。

这里使用加密方法,看了一下他们的介绍,加密算法是Diffie-Hellman 密钥交换算法,很好!

这样来看,它起码是一个很好的ajax工具,非常不错!


然后尝试一下发送一个Map和自定义pojo型数据:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>test.html</title>
	
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="this is my page">
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    
    <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->
	<script type="text/javascript" src="js/phprpc_client.js"></script>
	<script type="text/javascript">
		var client = new PHPRPC_Client('http://localhost:10010/phprpc-test/phprpc/', ['hello', 'getData1','sendData','sendData1']);  
		client.setKeyLength(256);  
		client.setEncryptMode(2);	
		/*
		client.hello('你好',function (result, args, output, warning) {  
		    alert(result); 
		});	  
		client.getData1(function (result, args, output, warning) {  
		    console.log(result);
		    alert(result.map['m1']); 
		});*/
		var cdata = {s1:'client string',map:{'k1':'cstring'}};
		client.sendData1(cdata,function (result, args, output, warning) {  
		    //console.log(result);
		   // alert(result.map['m1']); 
		});
		
		var data = {'k1':'cstring'};
		client.sendData(data,function (result, args, output, warning) {  
		    //console.log(result);
		   // alert(result.map['m1']); 
		});
	</script>
  </head>
  
  <body>
    
  </body>
</html>

可以看到调用了sendData方法,传入的是个json,sendData1传入的也是个与Cdata类型相配的json.

服务端添加sendData函数:

package kzg.phprpc.hello.service;

import java.util.Map;

import org.phprpc.util.Cast;

import kzg.phprpc.hello.api.Cdata;
import kzg.phprpc.hello.api.Hello;

public class HelloImpl implements Hello
{
	public String hello(String msg)
	{
		return "这是travel back from server:" + msg;
	}

	public Cdata getData1()
	{
		Cdata data = new Cdata("server data");
		return data;
	}

	public void sendData1(Cdata data)
	{
		System.out.println("call---- sendData1:" + Cast.cast(data.getMap().get("k1"),String.class));
	}
	
	public void sendData(Map data)
	{
		System.out.println("call---- sendData:" + Cast.cast(data.get("k1"),String.class));
	}
	
	
}

在Map里面直接取get(“k1”)是不行的,还要使用Cast.cast方法转换一下。

同样pojo类型中的相容型数据是转过来了,但是对于数组等容器类型,还得自己再处理一下。

我觉得这样就比较繁琐了,不过传复杂类型参数可以使用别的方法解决,使用json同样存在这样的问题,这里自动将json转为pojo,还是减省了一步。

见:

http://phprpc.org/zh_CN/docs/#[[PHPRPC%20for%20Java%20%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98%E8%A7%A3%E7%AD%94]]

另外一些问题 :

找半天不知道怎么处理异常,出了错,什么也没有。文档还是不全!这些基本的东西,要找半天。


Total views.

© 2013 - 2018. All rights reserved.

Powered by Hydejack v6.6.1