. Which works just fi" /> . Which works just fi" /> . Which works just fi"/>

HTML: Compiling python code in JSON format using a websocket server for real time output

27 views Asked by At

I am attempting to create a website in which the user selects python files where the code is displayed into the "code" <textarea>. Which works just fine, I am attempting to allow the user to input commands as per the python files valid responses. The direct problem I'm having is with the websocket. I installed composer, then ratchet having installed with powershell in the VS code terminal, I entered "composer require cboden/ratchet" in my project directory. The vendor folder is in my directory with all the relevant scripts. You can find my full code below:

My HTML and javascript inline:

<!DOCTYPE html>
<html lang="en">

<head>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>

    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <link rel="stylesheet" href="projectstyle.css">

    <title>Portfolio - Projects</title>

    <script>

$(document).ready(function() {
    var websocket;

    // Function to handle WebSocket connection
    function connectWebSocket() {
        var wsUrl = "ws://localhost:5669";

        // Initialize WebSocket connection
        websocket = new WebSocket(wsUrl);

        // WebSocket onopen event handler
        websocket.onopen = function(event) {
            console.log("WebSocket connection established.");
        };

        // WebSocket onmessage event handler
        websocket.onmessage = function(event) {
            try {
                var data = JSON.parse(event.data);
                console.log("Response from server:", data);

                // Display the output in the output box
                $('#outputBox').val(data.output);
            } catch (error) {
                console.error("Error parsing JSON:", error);
            }
        };

        // WebSocket onclose event handler
        websocket.onclose = function(event) {
            console.log("WebSocket connection closed:", event);
            // Attempt to reconnect after a delay
            setTimeout(connectWebSocket, 3000);
        };

        // WebSocket onerror event handler
        websocket.onerror = function(error) {
            console.error("WebSocket error:", error);
        };
    }

    // Function to load Python code into textarea when a file is selected from dropdown
    $('#fileList').change(function() {
        var selectedFile = $(this).val();
        // AJAX request to load file content
        $.ajax({
            url: selectedFile,
            dataType: 'text',
            success: function(data) {
                $('#code').val(data);
            },
            error: function(xhr, status, error) {
                console.error('Error loading file:', error);
            }
        });
    });

    // Execute Python code and display output in output box
    $('#compileButton').click(function() {
        var pythonCode = $('#code').val();
        console.log('Python code:', pythonCode); // Debugging statement

        // Check if WebSocket connection is open
        if (websocket.readyState === WebSocket.OPEN) {
            // Send Python code to server
            websocket.send(JSON.stringify({ code: pythonCode }));
        } else {
            console.error("WebSocket connection is not open.");
        }
    });

    // Connect to WebSocket server when document is ready
    connectWebSocket();
});
    </script>
</head>

<body id="projectsPage">

    <div class="topnav">
        <a id="home" href="index.html">Home</a>
        <a id="projects" class="active" href="projects.html">Projects</a>
        <a id="contact" href="#contact">Contact</a>
        <h3 id="nameHeader" class="topRight">Brandon Gray</h3>
    </div>

    <div class="welcome">
        <div id="boxBackground"></div>
    </div>

    <div class="projectsMenu">
        <select id="fileList">
            <option value="none">Select file</option>
            <option value="test.py">Python Code 1</option>
            <option value="Brute force passcode.py">Python Code 2</option>
            <option value="Rougue like dungeon escape game.py">Python Code 3</option>
        </select>
        <textarea id="code"></textarea>
        <input type="text" id="userInput" placeholder="User Input"> <!-- User input textbox -->
        <button id="inputButton">Input</button> <!-- Button for inputting user data -->
        <button id="compileButton">Compile</button>
    </div>

    <textarea id="outputBox"></textarea> <!-- Output textarea -->

</body>

</html>

My python compiler script:

<?php
// Enable error reporting and display errors
error_reporting(E_ALL);
ini_set('display_errors', 1);

// Check if code is received via POST request
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // Get Python code from the POST data
    $pythonCode = isset($_POST['code']) ? $_POST['code'] : '';

    // Check if Python code is empty
    if (empty($pythonCode)) {
        echo json_encode(['error' => 'No Python code received']);
        exit;
    }

    // Debug: Log received Python code
    error_log('Received Python code: ' . $pythonCode);

    // Execute Python code
    ob_start(); // Start output buffering to capture the output
    passthru("python -c " . escapeshellarg($pythonCode) . " 2>&1", $returnCode); // Execute Python code and capture return code
    $output = ob_get_clean(); // Get the captured output and clear the buffer

    // Check if Python execution was successful
    if ($returnCode !== 0) {
        echo json_encode(['error' => 'Failed to execute Python code', 'output' => $output]);
        exit;
    }

    // Send the output back to the client as JSON
    echo json_encode(['output' => $output]);
} else {
    // Handle invalid requests (e.g., direct access to this script)
    http_response_code(405); // Method Not Allowed
    echo json_encode(['error' => 'Method Not Allowed']);
}
?>

My websocket script:

<?php
require __DIR__ . '/vendor/autoload.php';

use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;

class MyWebSocketServer implements MessageComponentInterface {
    protected $clients;

    public function __construct() {
        $this->clients = new \SplObjectStorage;
    }

    public function onOpen(ConnectionInterface $conn) {
        // Store the new connection to send messages to later
        $this->clients->attach($conn);
        echo "New connection! ({$conn->resourceId})\n";
    }

    public function onMessage(ConnectionInterface $from, $msg) {
        // No need to implement this method for now
    }

    public function onClose(ConnectionInterface $conn) {
        // Connection is closed, remove it from the list of active connections
        $this->clients->detach($conn);
        echo "Connection {$conn->resourceId} has disconnected\n";
    }

    public function onError(ConnectionInterface $conn, \Exception $e) {
        // Handle errors gracefully
        echo "An error has occurred: {$e->getMessage()}\n";
        $conn->close();
    }
}

// Start the WebSocket server
$server = new \Ratchet\WebSocket\WsServer(new MyWebSocketServer);
$loop = \React\EventLoop\Factory::create();
$socket = new \React\Socket\Server('0.0.0.0:5669', $loop);
$server = new \Ratchet\Server\IoServer($server, $socket, $loop);

echo "WebSocket server running at 0.0.0.0:5669\n";

$server->run();
?>

When I try to run my websocket_server.php I get thrown this:

PS C:\Users\brandon\OneDrive\HTML\Portfolio> php websocket_server.php
WebSocket server running at 0.0.0.0:5669
PHP Fatal error:  Uncaught UnexpectedValueException: $request can not be null in C:\Users\brandon\OneDrive\HTML\Portfolio\vendor\cboden\ratchet\src\Ratchet\WebSocket\WsServer.php:110
Stack trace:
#0 C:\Users\brandon\OneDrive\HTML\Portfolio\vendor\cboden\ratchet\src\Ratchet\Server\IoServer.php(92): Ratchet\WebSocket\WsServer->onOpen()
#1 C:\Users\brandon\OneDrive\HTML\Portfolio\vendor\evenement\evenement\src\EventEmitterTrait.php(143): Ratchet\Server\IoServer->handleConnect()
#2 C:\Users\brandon\OneDrive\HTML\Portfolio\vendor\react\socket\src\Server.php(88): Evenement\EventEmitter->emit()
#3 C:\Users\brandon\OneDrive\HTML\Portfolio\vendor\evenement\evenement\src\EventEmitterTrait.php(143): React\Socket\Server->React\Socket\{closure}()
#4 C:\Users\brandon\OneDrive\HTML\Portfolio\vendor\react\socket\src\TcpServer.php(254): Evenement\EventEmitter->emit()
#5 C:\Users\brandon\OneDrive\HTML\Portfolio\vendor\react\socket\src\TcpServer.php(235): React\Socket\TcpServer->handleConnection()  
#6 C:\Users\brandon\OneDrive\HTML\Portfolio\vendor\react\event-loop\src\StreamSelectLoop.php(246): React\Socket\TcpServer->React\Socket\{closure}()
#7 C:\Users\brandon\OneDrive\HTML\Portfolio\vendor\react\event-loop\src\StreamSelectLoop.php(213): React\EventLoop\StreamSelectLoop->waitForStreamActivity()
#8 C:\Users\brandon\OneDrive\HTML\Portfolio\vendor\cboden\ratchet\src\Ratchet\Server\IoServer.php(74): React\EventLoop\StreamSelectLoop->run()
#9 C:\Users\brandon\OneDrive\HTML\Portfolio\websocket_server.php(45): Ratchet\Server\IoServer->run()
#10 {main}
  thrown in C:\Users\brandon\OneDrive\HTML\Portfolio\vendor\cboden\ratchet\src\Ratchet\WebSocket\WsServer.php on line 110

I investigated the WsServer.php file in my project directory and the code contained to errors on line 72 and 76 with the same error for "onMessage". It reads: Undefined method 'onMessage'.intelephense(P1013) I have tried running the websocket on different ports but to no avail. Sorry if this is a duplicate but I am fairly new to using websockets for websites and could use some more experienced eyes for my problem to help out.

Many thanks.

0

There are 0 answers