如何在 Symfony 5 中集成 Ratchet websocket?

问题描述

背景

我目前的设置是后端的 Symfony 5 API 和 Ratchet,前端的 Vue 2.6 和 vue-socket.oi-extended。我正在使用 Symfony encore,所以一切都在一个项目中。

我正在设置实时消息功能

问题

我目前在前端发出请求时收到 CORS 错误

从源“https://127.0.0.1:8000”访问“http://127.0.0.1:3001/socket.io/?EIO=4&transport=polling&t=NYhZwnE”的 XMLHttpRequest 已被 CORS 政策阻止:请求的资源上不存在“Access-Control-Allow-Origin”标头。

尝试修复

  1. 安装 Symfony cors 包并尝试了许多不同的配置。
  2. 在 index.PHP 中设置“Access-Control-Allow-Origin”标头。
  3. 在 Ratchet 中设置 new OriginCheck()

感谢任何帮助,请参阅下面我的代码

我按照 Ratchet 文档设置了 MessageService。

src/service/websocket/MessageService.PHP

<?PHP

namespace App\Service\Websocket;

use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;

class MessageService implements MessageComponentInterface {

  protected $clients;

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

    public function onopen(ConnectionInterface $conn) {
      $this->clients->attach($conn);
    }

    public function onMessage(ConnectionInterface $from,$msg) {
      foreach ($this->clients as $client) {
        if ($from != $client) {
            $client->send($msg);
        }
    }
    }

    public function onClose(ConnectionInterface $conn) {
      $this->clients->detach($conn);
    }

    public function onError(ConnectionInterface $conn,\Exception $e) {
      $conn->close();
    }
}

注册服务。

config/services.yaml

App\Service\Websocket\:
    resource: '../src/Service/Websocket'

我设置了一个命令来启动 websocket 服务器。

src/Command/WebsocketServerCommand.PHP

<?PHP
namespace App\Command;

use App\Service\Websocket\MessageService;
use Ratchet\Http\HttpServer;
use Ratchet\Server\IoServer;
use Ratchet\WebSocket\WsServer;
use App\Websocket\MessageHandler;
use Ratchet\Http\OriginCheck;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
 
class WebsocketServerCommand extends Command
{
    protected static $defaultName = "run:websocket-server";
 
    protected function execute(InputInterface $input,OutputInterface $output)
    {
      $port = 3001;
      $output->writeln("Starting server on port " . $port);
      
      $messageService = new MessageService();
      $ws = new WsServer($messageService);
      $httpServer = new HttpServer($ws);
      $server = IoServer::factory($httpServer,$port);

      $output->writeln("waiting...");
      $server->run();
      return 0;
    }
}

我运行命令 PHP bin/console run:websocket-server 并得到响应:

在端口 3001 上启动服务器 等待...

前端:

main.js (index.js)

import VueSocketIOExt from 'vue-socket.io-extended';
import { io } from 'socket.io-client';

const socket = io('http://127.0.0.1:3001');
Vue.use(VueSocketIOExt,socket,{ store });

export default 内的组件

sockets: {
    connect() {
      console.log("socket connected");
    },},

更新: 我尝试从 http://websocket.org/ 连接到 ws://127.0.0.1:3001,结果成功并且可以广播消息。

因此,问题必须出在前端或后端的 cors 配置上。

我在 index.PHP添加$response->headers->set('Access-Control-Allow-Origin','http://127.0.0.1:8080/');

我还在 http 而不是 https 上运行了 Symfony Web 服务器。 我卸载了 vue-socket.io-extended 并尝试了 vue-socket.io

每次更改后都会出现相同的 CORS 错误。这是胡说八道。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...