package org.hwo.rpc.json; import java.io.BufferedReader; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.net.InetAddress; import java.net.Socket; import java.net.URL; import java.net.URLConnection; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import org.json.simple.JSONValue; public class JSONRpcService implements InvocationHandler{ private String url; private InetAddress inetAddress; private int port; private Integer nextid; public JSONRpcService(String url){ this.url = url; this.nextid = 0; } public JSONRpcService(InetAddress inetAddress,int port){ this.inetAddress = inetAddress; this.port = port; } public T createProxy(Class iface){ T proxy = (T) Proxy.newProxyInstance(iface.getClassLoader(), new Class[]{ iface }, this); return proxy; } private byte[] request(byte[] request) throws Throwable{ if (url != null) return requestURL(request); if (inetAddress != null) return requestTCP(request); return new byte[0]; } private byte[] requestURL(byte[] request) throws Throwable{ URL url = new URL(this.url); URLConnection conn = url.openConnection(); conn.setDoInput(true); conn.setDoOutput(true); OutputStream out = conn.getOutputStream(); out.write(request); out.flush(); out.close(); BufferedReader reader = new BufferedReader(new InputStreamReader( conn.getInputStream())); StringBuilder sb = new StringBuilder(); String line; while ((line = reader.readLine())!=null) { sb.append(line); } return sb.toString().getBytes(); } private byte[] requestTCP(byte[] request) { try { Socket socket = new Socket(inetAddress,port); DataInputStream dis = new DataInputStream(socket.getInputStream()); DataOutputStream dos = new DataOutputStream(socket.getOutputStream()); dos.writeInt(request.length); dos.write(request); int len = dis.readInt(); byte[] response = new byte[len]; dis.read(response,0,len); dis.close(); dos.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } return new byte[0]; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { HashMap req = new HashMap(); req.put("id", this.nextid++ ); req.put("method", method.getName()); req.put("params", Arrays.asList(args)); String reqString = JSONValue.toJSONString(req); System.err.println(reqString); byte[] responseBytes = request( reqString.getBytes() ); System.err.println("Response: " + new String(responseBytes)); Map response = (Map)JSONValue.parse(new String(responseBytes)); if (response.containsKey("error") && (response.get("error") != null)) { throw new RuntimeException("JSON-RPC: " + response.get("error")); } return response.get("result"); } }