在 PHP 中通过 websockets 向客户端发送消息的正确过程?

问题描述 投票:0回答:1

我正在开发一个 Symfony 6 项目,在其中一个屏幕中,我想在按下按钮时开始执行 .jar。我已经设法异步执行它,但我无法通知客户端该过程已完成,因此我决定使用 websockets。我首先做了一个小设计来测试它们,由于某种原因,客户端只连接到网络服务器,但它不接收任何消息。

这是我的 JavaScript 文件

// WebSocket setup
const socket = new WebSocket('ws://localhost:8080');

socket.addEventListener('open', event => {
    console.log('Connected');
});

socket.addEventListener('message', event => {
    const message = JSON.parse(event.data);
    if (message.type === 'progress') {
        console.log(message.text);
    }
});

socket.addEventListener('close', event => {
    console.log('Connection closed');
});

// Fetch request
document.getElementById('upload-button').addEventListener('click', () => {
    const fileInput = document.getElementById('zip-file');
    
    const formData = new FormData(); // Create a new FormData object
    formData.append('del-file', fileInput.files[0]); // Append the selected file to the FormData
  
    fetch('/start-process', {
        method: 'POST',
        body: formData, // Send the FormData as the request body
    })
    .then(response => response.json())
    .then(data => console.log(data))
    .catch(error => console.error('Error:', error));
});

这将是按下按钮时调用的函数

/**
     * @Route("/start-process", name="start_process", methods={"POST"})
     */
    public function startProcess(Request $request, MessageBusInterface $messageBus, WebSocketServer $webSocketServer): JsonResponse
    {
        // Start the asynchronous background job
        $message = ['type' => 'progress', 'text' => 'Job started'];
        $webSocketServer->broadcast(json_encode($message));

        // Simulate background job
        sleep(2); // Simulate work
        $message = ['type' => 'progress', 'text' => 'Job in progress...'];
        $webSocketServer->broadcast(json_encode($message));
        sleep(2); // Simulate work
        // Simulate background job completion
        $message = ['type' => 'progress', 'text' => 'Job completed'];
        $webSocketServer->broadcast(json_encode($message));
        return $this->json(['message' => 'Process finished']);
    }

This is the only output that I receive in the console log

php ratchet
1个回答
0
投票

我将其作为答案输入,因为它很长。

您在这里遇到的根本问题是您的 Websocket 是在与 Web 服务器不同的进程中打开的。如果您希望两者进行交互,则必须在同一进程中处理它们。这可能意味着混合这两个包,这样您就可以响应 websocket 请求和 Web 服务器请求。请注意,您需要某种方式将两者关联起来;您不能假设您只有一个客户端,因此您可能有多个 Web 套接字,您需要将它们分配给正确的 Web 会话。

请允许我针对您所讨论的内容提出替代策略。不要创建 Web 套接字,而是在前端使用 Javascript 循环,使用正常的

fetch
请求每秒左右轮询后端。然后,它就成为后端要处理的另一个 API,以返回操作的当前状态。

这是处理长时间运行的后台任务的一种非常常见的模式,并且比管理 Web 套接字简单得多。您甚至可以在线找到此代码。

© www.soinside.com 2019 - 2024. All rights reserved.