From 3878f359949d304ec4b925e21af38cd5bf7e0051 Mon Sep 17 00:00:00 2001 From: jrtechs Date: Sun, 27 May 2018 10:34:38 -0400 Subject: [PATCH] Worked on server side web socket which sends the client updates to draw their graph. --- src/main/java/net/jrtechs/www/Player.java | 17 ++- .../jrtechs/www/graphDB/GremlinConsole.java | 129 ++++++++++++++++++ .../net/jrtechs/www/graphDB/SteamGraph.java | 81 +++++++++++ .../java/net/jrtechs/www/server/Client.java | 116 +++++++++++++++- .../java/net/jrtechs/www/server/Server.java | 8 +- 5 files changed, 345 insertions(+), 6 deletions(-) create mode 100644 src/main/java/net/jrtechs/www/graphDB/GremlinConsole.java diff --git a/src/main/java/net/jrtechs/www/Player.java b/src/main/java/net/jrtechs/www/Player.java index da3e055..5d0de26 100644 --- a/src/main/java/net/jrtechs/www/Player.java +++ b/src/main/java/net/jrtechs/www/Player.java @@ -66,10 +66,20 @@ public class Player .forEach(f-> this.friends.add( new Player(con.getPlayerName(f), f))); } - return friends; } + + /** + * Returns a list of all the friends of a specific player + * + * @return + */ + public List fetchFriends() + { + return this.friends; + } + /** * Getter for display name of player * @@ -91,6 +101,11 @@ public class Player return this.id; } + public void setFriends(List friends) + { + this.friends = friends; + } + @Override public String toString() diff --git a/src/main/java/net/jrtechs/www/graphDB/GremlinConsole.java b/src/main/java/net/jrtechs/www/graphDB/GremlinConsole.java new file mode 100644 index 0000000..7de16e0 --- /dev/null +++ b/src/main/java/net/jrtechs/www/graphDB/GremlinConsole.java @@ -0,0 +1,129 @@ +package net.jrtechs.www.graphDB; + +import org.apache.tinkerpop.gremlin.driver.ResultSet; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.stream.IntStream; + + +/** + * Class used to test connection with remote database and issue queries while + * developing our project + * + * @author Jeffery Russell 8-25-18 + */ +public class GremlinConsole +{ + /** Connection to graph server **/ + private RemoteConnection connection; + + + /** + * Instantiates the remote connection + */ + public GremlinConsole() + { + this.connection = new RemoteConnection(); + } + + + /** + * Fetches remote connection of the console + * + * @return + */ + public RemoteConnection getConnection() + { + return this.connection; + } + + + + /** + * Gets input from the user and queries the graph server and prints out + * the output. + * + * There is excessive try catching to prevent a bad query/input from crashing + * the console + */ + public void run() + { + BufferedReader br = null; + + try + { + br = new BufferedReader(new InputStreamReader(System.in)); + + while (true) + { + + System.out.print("Enter Query: "); + String input = br.readLine(); + + if ("q".equals(input)) + { + System.out.println("Exit!"); + System.exit(0); + } + + ResultSet set = this.connection.queryGraph(input); + try + { + set.forEach(System.out::println); + } + catch (Exception ex) + { + ex.printStackTrace(); + } + + } + + } + catch (Exception e) + { + e.printStackTrace(); + } + finally + { + if (br != null) + { + try + { + br.close(); + } catch (IOException e) + { + e.printStackTrace(); + } + } + } + } + + + /** + * Makes this script runnable as a stand alone application for use + * + * To run queries from command line arguments, surround them with double + * quotes and add spaces between queries + * + * ex usage: + * "g.V().hasLabel('Satellite').values('OBJECT_ID')" "g.V().hasLabel + * ('Country').has('abr', 'US').valueMap()" + * + * @param args + */ + public static void main(String args[]) + { + GremlinConsole console = new GremlinConsole(); + + //don't worry about this lambda + IntStream.range(0, args.length) + .forEach(i-> console.getConnection() + .queryGraph(args[i]) + .forEach((System.out::println))); + + console.run(); + } + +} diff --git a/src/main/java/net/jrtechs/www/graphDB/SteamGraph.java b/src/main/java/net/jrtechs/www/graphDB/SteamGraph.java index 1a6f5e4..053f375 100644 --- a/src/main/java/net/jrtechs/www/graphDB/SteamGraph.java +++ b/src/main/java/net/jrtechs/www/graphDB/SteamGraph.java @@ -3,6 +3,11 @@ package net.jrtechs.www.graphDB; import net.jrtechs.www.Player; import net.jrtechs.www.SteamAPI.APIConnection; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Optional; + /** * Does graph based operations with {@link Player} * and {@link RemoteConnection} @@ -126,6 +131,13 @@ public class SteamGraph } } + + /** + * Recursive function for scraping the steam api + * + * @param player + * @param debth + */ public void insertIntoGraph(Player player, int debth) { insertIntoGraph(player); @@ -138,6 +150,75 @@ public class SteamGraph } + /** + * Fetches the name of the player from the graph database + * + * @param id + * @return + */ + private String getNameFromGraph(String id) + { + String query = "g.V().hasLabel('player')" + + ".has('id', '" + id + "')" + + ".values('name')"; + return this.con.queryGraph(query).stream() + .findFirst().get().getObject().toString(); + } + + + /** + * Fetches a list of friends from the graph database + * + * @param id + * @return + */ + private List getFriendsFromGraph(String id) + { + List friends = new ArrayList<>(); + + String query = "g.V().hasLabel('player')" + + ".has('id', '" + id + "')" + + ".both().valueMap()"; + + this.con.queryGraph(query).stream().forEach(r-> + friends.add(new Player( + ((ArrayList) (((HashMap)(r.getObject())) + .get("name"))).get(0).toString(), + ((ArrayList)(((HashMap)(r.getObject())) + .get("id"))).get(0).toString())) + ); + + return friends; + } + + + + /** + * Fetches a player from the graph + * + * @param id + * @return + */ + public Player getPlayerInformation(String id) + { + Player p; + if(!this.alreadyInGraph(id)) + { + p = new Player(id); + this.insertIntoGraph(p); + } + else + { + p = new Player(this.getNameFromGraph(id), id); + System.out.println(p.getName()); + } + + p.setFriends(this.getFriendsFromGraph(id)); + + return p; + } + + /** * * @param args diff --git a/src/main/java/net/jrtechs/www/server/Client.java b/src/main/java/net/jrtechs/www/server/Client.java index c62f7dc..7acfa96 100644 --- a/src/main/java/net/jrtechs/www/server/Client.java +++ b/src/main/java/net/jrtechs/www/server/Client.java @@ -1,31 +1,141 @@ package net.jrtechs.www.server; +import net.jrtechs.www.Player; +import net.jrtechs.www.graphDB.SteamGraph; import org.java_websocket.WebSocket; +import org.json.JSONObject; + +/** + * Client thread which gets graph information from + * the graphDB and sends it to the client so that + * they can render it in their web browser. + * + * @author Jeffery Russell 5-27-18 + */ public class Client extends Thread { - + /** Web connection to the client */ private WebSocket client; + /** Graph interface to fetch data */ + private SteamGraph graph; + + /** base id to look at */ + private String baseId; + + /** How many layers of friends we are traversing */ + private int debth; + /** + * Initializes the client with a steam graph and + * web socket information. + * @param client + */ public Client(WebSocket client) { this.client = client; + this.graph = new SteamGraph(); + + //temp stuff + this.baseId = "76561198188400721"; + this.debth = 1; } - public void recievedMessage(String message) + + /** + * Method which is called when the client sends a message + * to the server. + * + * @param message + */ + public void receivedMessage(String message) { } + + /** + * returns the web socket object + * + * @return + */ public WebSocket getSocket() { return this.client; } + + /** + * Sends the client the request to add a new node to their + * graph. + * + * @param p + */ + private void sendNodeAdd(Player p) + { + JSONObject request = new JSONObject(); + request.put("action", 1); + request.put("id", p.getId()); + request.put("name", p.getName()); + + this.sendJSON(request); + } + + + /** + * Sends the client to request to connect two nodes + * via an edge. + * + * @param p1 + * @param p2 + */ + private void sendEdgeAdd(Player p1, Player p2) + { + JSONObject request = new JSONObject(); + request.put("action", 2); + request.put("id", p1.getId() + p2.getId()); + request.put("p1", p1.getId()); + request.put("p2", p2.getId()); + + this.sendJSON(request); + } + + + private void sendJSON(JSONObject request) + { + System.out.println("sending " + request.toString()); + this.client.send(request.toString()); + } + + + /** + * Sends an entire player and all of their friends to the client + * + * @param p + */ + private void sendPlayerToClient(Player p) + { + sendNodeAdd(p); + + for(Player friend: p.fetchFriends()) + { + this.sendNodeAdd(friend); + + this.sendEdgeAdd(p, friend); + } + } + + + /** + * Where the magic happens + */ @Override - public void run() { + public void run() + { + Player b = this.graph.getPlayerInformation(this.baseId); + this.sendPlayerToClient(b); } } diff --git a/src/main/java/net/jrtechs/www/server/Server.java b/src/main/java/net/jrtechs/www/server/Server.java index d5067ab..6657ebd 100644 --- a/src/main/java/net/jrtechs/www/server/Server.java +++ b/src/main/java/net/jrtechs/www/server/Server.java @@ -36,7 +36,11 @@ public class Server extends WebSocketServer @Override public void onOpen(WebSocket conn, ClientHandshake handshake) { - clients.add(new Client(conn)); + Client newClient = new Client(conn); + clients.add(newClient); + + newClient.start(); + System.out.println("New connection from " + conn.getRemoteSocketAddress().getAddress().getHostAddress()); } @@ -58,7 +62,7 @@ public class Server extends WebSocketServer { if(client.getSocket() == conn) { - client.recievedMessage(message); + client.receivedMessage(message); } } }