package pl.icedev.rpc.client;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import java.io.*;
import java.net.Socket;
public class JSONRPC implements Closeable {
private Socket sock;
private int counter;
private String authKey;
private PrintStream writer;
private BufferedReader reader;
private JSONParser parser;
public JSONRPC(String host, int port) throws IOException {
this.counter = 1;
this.sock = null;
this.authKey = null;
this.sock = new Socket(host, port);
this.writer = new PrintStream(sock.getOutputStream(), true, "UTF8");
this.reader = new BufferedReader(new InputStreamReader(sock.getInputStream(), "UTF8"));
this.parser = new JSONParser();
}
public void setAuthKey(String authKey) {
this.authKey = authKey;
}
@Override
public void close() {
if (sock != null) {
try {
sock.close();
} catch (IOException e) {
// ignore in this case
}
}
}
public Object call(String method, Object... args) {
JSONObject json = new JSONObject();
json.put("method", method);
json.put("params", args);
json.put("id", ++counter);
if (authKey != null) {
json.put("authKey", authKey);
}
writer.println(json.toJSONString());
writer.flush();
try {
String resStr = reader.readLine();
Object obj = parser.parse(resStr);
if (obj instanceof JSONObject) {
json = (JSONObject) obj;
if (json.containsKey("error")) {
try {
JSONObject error = (JSONObject) json.get("error");
int code = (int) (long) error.get("code");
throw new RPCException(code, String.valueOf(error.get("message")));
} catch (ClassCastException e) {
throw new RPCException(-32603, "Received an invalid error object.");
}
}
if (!json.containsKey("result")) {
throw new RPCException(-32603, "Missing field result in response object.");
}
return json.get("result");
}
throw new RPCException(-32603, "Invalid response object.");
} catch (IOException | ParseException e) {
throw new RPCException(-32603, "Failed to process response.", e);
}
}
}