@Override
 public void onOpen() {
   try {
     client.sendMethodList();
   } catch (IOException e) {
     e.printStackTrace();
   } catch (JSONException e) {
     e.printStackTrace();
   }
 }
 @Override
 public void onMessage(String message) {
   try {
     JSONObject msg = new JSONObject(message);
     String type = msg.getString("type");
     if (type.equals("message")) {
       client.getOnMessage().onMessage(msg.get("content"));
     } else if (type.equals("response")) {
       long id = msg.getLong("id");
       Object content = msg.get("content");
       GamenodeStub stub = client.getStub();
       stub.getCallback(id).exec(content);
     } else if (type.equals("call")) {
       long id = msg.getLong("id");
       String method = msg.getString("method");
       Object params = msg.get("params");
       GamenodeSkeleton skel = client.getSkeleton();
       try {
         Object returnValue = skel.call(method, params);
         client.sendResponse(id, returnValue);
       } catch (NoSuchMethodException e) {
         client.sendError("Unknown method: " + method);
       }
     } else if (type.equals("error")) {
       String content = msg.getString("content");
       client.getOnError().onError(content);
     } else if (type.equals("methodList")) {
       List<String> methods = new ArrayList<String>();
       JSONArray methodList = msg.getJSONArray("content");
       for (int i = 0; i < methodList.length(); ++i) {
         String methodName = methodList.getString(i);
         if (methodName != null) {
           methods.add(methodName);
         }
       }
       GamenodeStub stub = new GamenodeStubImpl(methods, client);
       client.setStub(stub);
       client.getOnConnect().onConnect();
     }
   } catch (JSONException e) {
     System.err.println("ERROR: Invalid message: " + message);
   } catch (IOException e) {
     e.printStackTrace();
   }
 }