-
IsolatedSushi authoredIsolatedSushi authored
webSocketGateway.js 4.72 KiB
const WebSocket = require('ws');
var grpc = require("./grpcConnection")
var grpcJS = require('@grpc/grpc-js');
//Setup webserver
const webSocketHost = "0.0.0.0"
const webSocketPort = 9898
var projectorTarget = process.env.PROJECTOR_TARGET ||'127.0.0.1:50051'; //var target = "proveeprojectorservice:50051"
var knnTarget = process.env.KNN_TARGET || '127.0.0.1:50052'; //"proveeknnservice:50052"
const wsServer = new WebSocket.Server({ host: webSocketHost, port: webSocketPort });
console.log("Projector target " +projectorTarget);
console.log("KNN target: " + knnTarget)
var projectorPackage = grpc.getGRPCPackage( __dirname + '/../protos/v3/projector.proto');
var KNNPackage = grpc.getGRPCPackage(__dirname + '/../protos/v3/knn.proto');
var pointID = 0;
class ProjectionRequest{
constructor(ws){
this.index = 0;
this.ws = ws;
this.projectorConn = null;
this.knnConn = null;
this.lineAmount = 0;
}
}
wsServer.on('connection', function connection(ws) {
console.log(`Client connected with websocket`);
var currConnection = new ProjectionRequest(ws);
ws.on('message', function incoming(message) {
parseMessage(message, currConnection);
});
ws.on('close', (code, reason) => {
console.log("Closed");
if (currConnection.client) {
grpc.closeClient(client);
}
})
});
//Notify client of error
function sendError(ws,message){
ws.send(JSON.stringify({type: "error", message: message}));
}
function KNNNeighbourRequest(connection,words,k){
console.log("Requesting " + words);
const meta = new grpcJS.Metadata();
meta.add('id',connection.knnConn.id);
connection.knnConn.client.getKNNRequest({k:k,words: words},meta,function(err,response){
if(response){
console.log("got response");
sendNeighbour(response,connection.ws);
return;
}
sendError(connection.ws,"No valid request: " + words)
console.log(err);
});
}
//Parse the message from browser
function parseMessage(message, connection) {
const jsonMessage = JSON.parse(message);
switch (jsonMessage["type"]) {
case "requestPointStream":
console.log("Requested stream");
sendRandomPointStream(connection);
break;
case "sendDataRow":
grpc.sendRowToServer(jsonMessage["row"], [connection.projectorConn,connection.knnConn]);
break;
case "setLineCount":
connection.lineAmount = parseInt(jsonMessage["amount"]);
break;
case "getKNNNeighbours":
var k = parseInt(jsonMessage["amount"]);
var words = jsonMessage["word"]
if(!connection.knnConn){
console.log("No KNN microservice");
sendError(connection.ws,"No KNN microservice")
break;
}
KNNNeighbourRequest(connection,words,k);
break;
case "getKNN":
console.log("setup KNN");
connection.knnConn = grpc.getGRPCClient(knnTarget,KNNPackage,"KNN");
grpc.getKNNConnection(connection)
break;
case "setProjectorAmount":
var amount = parseInt(jsonMessage["amount"]);
connection.projectorConn =grpc.getGRPCClient(projectorTarget,projectorPackage,"Projector");
SetupKProjectors(amount,connection)
break;
default:
console.log("Error! Unknown request:" + jsonMessage["type"]);
}
}
function SetupKProjectors (amount,connection){
var allCalls = []
//Create that amount of grpc connections
for(var i = 0; i< amount; i++){
var call = connection.projectorConn.client.getProjectionPoints()
var grpcConnection = grpc.getGRPCBidirect(connection.ws,call,sendDataStreamToClient);
allCalls.push(grpcConnection)
}
connection.projectorConn.calls = allCalls;
}
function generatePoints() {
var pointChunk = []
for(var i = 0; i < 100; i++){
const id = pointID++;
const x = Math.floor(Math.random() * 100);
const y = Math.floor(Math.random() * 100);
pointChunk.push({ id, x, y })
}
return {points: pointChunk};
}
//Get the stream
function sendRandomPointStream(connection) {
for (var i = 0; i < 1000; i++) {
sendDataStreamToClient(generatePoints(), connection.ws);
}
}
//Result from KNN request
function sendNeighbour(response,ws){
if(!response || response["rows"].length == 0){
const errMSG = "The word (or one of the words) was not in the set (or hasnt been received yet)";
console.log(errMSG);
sendError(ws,errMSG)
return;
}
for(var i = 0; i < response["rows"].length; i++){
console.log(response["rows"][i]["id"] + " " + response["rows"][i]["distance"]);
ws.send(JSON.stringify({type: "neighbour", neighbour: response["rows"][i]["id"],distance: response["rows"][i]["distance"].toString()}));
}
}
//Send client to browser
function sendDataStreamToClient(data, ws) {
var rows = data["points"]
ws.send(JSON.stringify({type: "points", points: rows}));
}