Codemaxxers / Issues

0 stars 0 forks source link

Triangle Ticket: Rachit, Tanisha, Luna #72

Open rachit-j opened 2 months ago

rachit-j commented 2 months ago

Rachit

As stated, did lots of research and digging into websockets to make them work. Now, they work with different commands and a framework to run them, which was also created by rachit.

image

To deploy on nginx, did lots of research into why nginx was blocking websockets through postman. Found new nginx configurations had to be placed for deployment.

image

Specific settings for websockets in nginx

w/out certbot config

server {
    listen 80;
    listen [::]:80;
    server_name codemaxxerlink.stu.nighthawkcodingsociety.com;

    location / {
        proxy_pass http://localhost:8033;  # Ensure this matches the internal port your app runs on
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;  # Required for WebSocket
        proxy_set_header Connection $connection_upgrade;  # Required for WebSocket
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # Handling CORS for simple and preflighted requests
        if ($request_method ~* "(GET|POST|PUT|DELETE|OPTIONS)") {
            add_header "Access-Control-Allow-Origin" *;
            add_header "Access-Control-Allow-Methods" "GET, POST, PUT, DELETE, OPTIONS";
            add_header "Access-Control-Allow-Headers" "Authorization, Origin, X-Requested-With, Content-Type, Accept";
            if ($request_method = OPTIONS) {
                return 204;  # Return 'No Content' for OPTIONS preflight request
            }
        }
    }
}

# Map necessary for WebSocket upgrades
map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}

w/ certbot config...

server {
    server_name codemaxxerlink.stu.nighthawkcodingsociety.com; # Change server name to the one on R53

    # Configure CORS Headers for typical HTTP requests
    location / {
        proxy_pass http://localhost:8033; # Change port to port on Docker
        proxy_http_version 1.1;  # Ensures HTTP/1.1 is used, which is necessary for WebSocket upgrades
        proxy_set_header Upgrade $http_upgrade; # Required for WebSocket
        proxy_set_header Connection $connection_upgrade; # Required for WebSocket
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # Simple requests
        if ($request_method ~* "(GET|POST|PUT|DELETE)") {
            add_header "Access-Control-Allow-Origin" *;
        }
        # Preflighted requests
        if ($request_method = OPTIONS) {
            add_header "Access-Control-Allow-Origin" *;
            add_header "Access-Control-Allow-Methods" "GET, POST, PUT, DELETE, OPTIONS, HEAD"; # Make sure the request methods above match here
            add_header "Access-Control-Allow-Headers" "Authorization, Origin, X-Requested-With, Content-Type, Accept";
            return 200;
        }
    }

    listen [::]:443 ssl; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/codemaxxerlink.stu.nighthawkcodingsociety.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/codemaxxerlink.stu.nighthawkcodingsociety.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server {
    if ($host = codemaxxerlink.stu.nighthawkcodingsociety.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    listen 80;
    listen [::]:80;
    server_name codemaxxerlink.stu.nighthawkcodingsociety.com;
    return 404; # managed by Certbot
}

# Necessary for WebSocket upgrade
map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}

For more, ask for live demo. Rachit will explain everything he has done in more detail.

Luna

tanishapatil1234 commented 2 months ago

Tanisha

Link to previous issue

image

For this checkpoint I addressed all the goals I had from last time.

NaN Fixes

Here are the changes I made:

Backend (PredictionController.java) @GetMapping("/api/predictAPScore") public double predictAPScore(@RequestParam int csaPoints) { // Call predictAPScore method of the prediction model return predictionModel.predictAPScore(csaPoints); }

Frontend (testing and dashboard) function predictAndDisplayAPScore(csaPoints) { console.log("Sending request with csaPoints:", csaPoints); fetch("http://localhost:8032/api/predictAPScore?csaPoints=" + csaPoints) .then(response => { console.log("Received response:", response); if (!response.ok) { throw new Error('Network response was not ok'); } return response.json(); }) .then(data => { console.log("Received data:", data); // Ensure the predicted AP score is between 1 and 5 const predictedAPScore = Math.min(Math.max(Math.round(data), 1), 5); document.getElementById("predictedAPScoreDisplay").innerText = Predicted AP Score: ${predictedAPScore}; }) .catch(error => { console.error('There was a problem with the fetch operation:', error); document.getElementById("predictedAPScoreDisplay").innerText = 'Failed to fetch prediction result.'; }); }

Capping AP Score Prediction

function predictAndDisplayAPScore(csaPoints) { console.log("Sending request with csaPoints:", csaPoints); fetch("http://localhost:8032/api/predictAPScore?csaPoints=" + csaPoints) .then(response => { console.log("Received response:", response); if (!response.ok) { throw new Error('Network response was not ok'); } return response.json(); }) .then(data => { console.log("Received data:", data); // Ensure the predicted AP score is between 1 and 5 const predictedAPScore = Math.min(Math.max(Math.round(data), 1), 5); document.getElementById("predictedAPScoreDisplay").innerText = Predicted AP Score: ${predictedAPScore}; }) .catch(error => { console.error('There was a problem with the fetch operation:', error); document.getElementById("predictedAPScoreDisplay").innerText = 'Failed to fetch prediction result.'; }); }

Adding Graphs and Interaction

image

years = [int(year) for year in data.keys()] x = [entry["y"] for entry in data.values()] y = [entry["x"] for entry in data.values()]

trace_temperature = go.Scatter( x=x, y=y, mode='markers', name='A' )

trace_rainfall = go.Scatter( x=x, y=y, mode='markers', name='B' )

layout = go.Layout( title='Title', xaxis=dict(title='x'), yaxis=dict(title='y'), hovermode='closest' )

fig = go.Figure(data=[x, y], layout=layout)

plotly.offline.plot(fig, filename='tester.html', auto_open=False)

image

parsed_data = json.loads(data)

years = list(parsed_data['Data'].keys()) populations = list(parsed_data['Data'].values())

fig = go.Figure(data=[go.Bar( x=x, y=y, marker=dict(color='rgb(138, 174, 235)', line=dict(color='rgb(8, 8, 97)', width=1.5)), )]) fig.update_layout( title='TITLE', xaxis=dict(title='X'), yaxis=dict(title='Y'), plot_bgcolor='rgba(0,0,0,0)', showlegend=False, ) fig.write_html('test.html')

Final implementation :

image image

const csaPointsSlider = document.getElementById('csaPointsSlider'); const csaPointsValue = document.getElementById('csaPointsValue');

csaPointsSlider.addEventListener('input', function (event) { const value = parseInt(event.target.value); csaPointsValue.innerText = value; predictAndDisplayAPScore(value); });

Researched Web Sockets

For MyHandler.java I wrote this function private void handleGetPlayerPosition(WebSocketSession session, String playerName) throws IOException { try { // Log request log.info("Fetching position for player: {}", playerName);

    String position = getPlayerPositionFromDatabase(playerName);

    session.sendMessage(new TextMessage("Position for " + playerName + ": " + position));
} catch (Exception e) {
    log.error("Error fetching player position: ", e);
    session.sendMessage(new TextMessage("Error fetching player position"));
}

}

private String getPlayerPositionFromDatabase(String playerName) { return "X: 100, Y: 200"; }

But Through testing and trying to add x and y instance variables to the original person class I discovered some errors:

The issue came from the absence of x and y parameters in the table/person class. I attempted to initialize them, but i had the complication of retrieving x and y coordinates from the frontend, which are locally stored but relative to individual users' screens, which is impractical for WebSocket functionality. So, an alternative solution is the tiled approach, as initially explored by Luna and me, where we would implement a standardized coordinate system enabling collision detection within the map file itself. So, updates would be sent to the conventional backend, which, in turn, would update the table in connections, which would allow for WebSocket updates. But because the coordinate system will still be on the local frontend we may have to reconsider or do some additional planninng on websockets. I have discusses this with rachit and we will be planning going forward.

Here I was trying to log the error in chatGPT

image
tanishapatil1234 commented 2 months ago

Tanisha

Link to previous issue

image

For this checkpoint I addressed all the goals I had from last time.

NaN Fixes

Here are the changes I made:

Backend (PredictionController.java) @GetMapping("/api/predictAPScore") public double predictAPScore(@RequestParam int csaPoints) { // Call predictAPScore method of the prediction model return predictionModel.predictAPScore(csaPoints); }

Frontend (testing and dashboard) function predictAndDisplayAPScore(csaPoints) { console.log("Sending request with csaPoints:", csaPoints); fetch("http://localhost:8032/api/predictAPScore?csaPoints=" + csaPoints) .then(response => { console.log("Received response:", response); if (!response.ok) { throw new Error('Network response was not ok'); } return response.json(); }) .then(data => { console.log("Received data:", data); // Ensure the predicted AP score is between 1 and 5 const predictedAPScore = Math.min(Math.max(Math.round(data), 1), 5); document.getElementById("predictedAPScoreDisplay").innerText = Predicted AP Score: ${predictedAPScore}; }) .catch(error => { console.error('There was a problem with the fetch operation:', error); document.getElementById("predictedAPScoreDisplay").innerText = 'Failed to fetch prediction result.'; }); }

Capping AP Score Prediction

function predictAndDisplayAPScore(csaPoints) { console.log("Sending request with csaPoints:", csaPoints); fetch("http://localhost:8032/api/predictAPScore?csaPoints=" + csaPoints) .then(response => { console.log("Received response:", response); if (!response.ok) { throw new Error('Network response was not ok'); } return response.json(); }) .then(data => { console.log("Received data:", data); // Ensure the predicted AP score is between 1 and 5 const predictedAPScore = Math.min(Math.max(Math.round(data), 1), 5); document.getElementById("predictedAPScoreDisplay").innerText = Predicted AP Score: ${predictedAPScore}; }) .catch(error => { console.error('There was a problem with the fetch operation:', error); document.getElementById("predictedAPScoreDisplay").innerText = 'Failed to fetch prediction result.'; }); }

Adding Graphs and Interaction

image

years = [int(year) for year in data.keys()] x = [entry["y"] for entry in data.values()] y = [entry["x"] for entry in data.values()]

trace_temperature = go.Scatter( x=x, y=y, mode='markers', name='A' )

trace_rainfall = go.Scatter( x=x, y=y, mode='markers', name='B' )

layout = go.Layout( title='Title', xaxis=dict(title='x'), yaxis=dict(title='y'), hovermode='closest' )

fig = go.Figure(data=[x, y], layout=layout)

plotly.offline.plot(fig, filename='tester.html', auto_open=False)

image

parsed_data = json.loads(data)

years = list(parsed_data['Data'].keys()) populations = list(parsed_data['Data'].values())

fig = go.Figure(data=[go.Bar( x=x, y=y, marker=dict(color='rgb(138, 174, 235)', line=dict(color='rgb(8, 8, 97)', width=1.5)), )]) fig.update_layout( title='TITLE', xaxis=dict(title='X'), yaxis=dict(title='Y'), plot_bgcolor='rgba(0,0,0,0)', showlegend=False, ) fig.write_html('test.html')

Final implementation :

image image

const csaPointsSlider = document.getElementById('csaPointsSlider'); const csaPointsValue = document.getElementById('csaPointsValue');

csaPointsSlider.addEventListener('input', function (event) { const value = parseInt(event.target.value); csaPointsValue.innerText = value; predictAndDisplayAPScore(value); });

Researched Web Sockets

For MyHandler.java I wrote this function private void handleGetPlayerPosition(WebSocketSession session, String playerName) throws IOException { try { // Log request log.info("Fetching position for player: {}", playerName);

    String position = getPlayerPositionFromDatabase(playerName);

    session.sendMessage(new TextMessage("Position for " + playerName + ": " + position));
} catch (Exception e) {
    log.error("Error fetching player position: ", e);
    session.sendMessage(new TextMessage("Error fetching player position"));
}

}

private String getPlayerPositionFromDatabase(String playerName) { return "X: 100, Y: 200"; }

But Through testing and trying to add x and y instance variables to the original person class I discovered some errors:

The issue came from the absence of x and y parameters in the table/person class. I attempted to initialize them, but i had the complication of retrieving x and y coordinates from the frontend, which are locally stored but relative to individual users' screens, which is impractical for WebSocket functionality. So, an alternative solution is the tiled approach, as initially explored by Luna and me, where we would implement a standardized coordinate system enabling collision detection within the map file itself. So, updates would be sent to the conventional backend, which, in turn, would update the table in connections, which would allow for WebSocket updates. But because the coordinate system will still be on the local frontend we may have to reconsider or do some additional planninng on websockets. I have discusses this with rachit and we will be planning going forward.

Here I was trying to log the error in chatGPT

image