Symfony 6+Ratchet开发实时聊天:WebSocket本地连接失败求助
问题:Symfony 6 + Ratchet 无法建立WebSocket连接
使用Symfony 6、Ratchet与JavaScript开发实时聊天功能,控制台显示连接URL(wss://localhost:8000/game)无误,但始终无法建立WebSocket连接。相关代码如下:
命令类代码
<?php namespace App\Command; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Ratchet\App; use Ratchet\Server\IoServer; use Ratchet\Http\HttpServer; use Ratchet\WebSocket\WsServer; use App\Websocket\MessageHandler; use App\Sockets\LiveChat; class SocketCommand extends Command { protected function configure() { $this->setName('sockets:start-chat') ->setHelp("Starts the chat socket demo") ->setDescription('Starts the chat socket demo'); } protected function execute(InputInterface $input, OutputInterface $output) { // $server = IoServer::factory( // new HttpServer( // new WsServer( // new LiveChat() // ) // ), // 8000 // ); $output->writeln([ 'Chat socket', '============', 'Starting chat, open your browser.', ]); //$app = new App('localhost', 8000, '127.0.0.1'); $app = new \Ratchet\App('127.0.0.1', 8000, '0.0.0.0'); $app->route('/game', new LiveChat); $app->run(); } }
WebSocket初始化类代码
<?php namespace App\Sockets; use Ratchet\MessageComponentInterface; use Ratchet\ConnectionInterface; use SplObjectStorage; class LiveChat implements MessageComponentInterface { protected $clients; public function __construct() { $this->clients = new SplObjectStorage; } public function onOpen(ConnectionInterface $conn) { $this->clients->attach($conn); echo "New connection! ({$conn->resourceId})\n"; } public function onMessage(ConnectionInterface $from, $msg) { $numRecv = count($this->clients) - 1; echo sprintf('Connection %d sending message "%s" to %d other connection%s' . "\n", $from->resourceId, $msg, $numRecv, $numRecv == 1 ? '' : 's'); foreach ($this->clients as $client) { if ($from !== $client) { // The sender is not the receiver, send to each client connected $client->send($msg); } } } public function onClose(ConnectionInterface $conn) { // The connection is closed, remove it, as we can no longer send it messages $this->clients->detach($conn); echo "Connection {$conn->resourceId} has disconnected\n"; } public function onError(ConnectionInterface $conn, \Exception $e) { echo "An error has occurred: {$e->getMessage()}\n"; $conn->close(); } }
前端JavaScript代码
var clientInformation = { username: new Date().getTime().toString() // You can add more information in a static object }; var conn = new WebSocket('ws://localhost:8000/game'); console.log(conn); conn.onopen = function(e) { console.info("Connection established succesfully"); }; conn.onmessage = function(e) { var data = JSON.parse(e.data); Chat.appendMessage(data.username, data.message); console.log(data); }; conn.onerror = function(e) { alert("Error: something went wrong with the socket."); console.error(e); }; document.getElementById("form-submit").addEventListener("click", function() { var msg = document.getElementById("form-message").value; if (!msg) { alert("Please send something on the chat"); } Chat.sendMessage(msg); document.getElementById("form-message").value = ""; }, false); var Chat = { appendMessage: function(username, message) { var from; if (username == clientInformation.username) { from = "me"; } else { from = clientInformation.username; } var ul = document.getElementById("chat-list"); var li = document.createElement("li"); li.appendChild(document.createTextNode(from + " : " + message)); ul.appendChild(li); }, sendMessage: function(text) { clientInformation.message = text; conn.send(JSON.stringify(clientInformation)); this.appendMessage(clientInformation.username, clientInformation.message); } };
解决要点
- 协议不匹配:后端未配置SSL证书,前端不能用
wss://,需改为ws://localhost:8000/game。 - 语法错误:
LiveChat类的onError方法中有多余字符w,已在代码中修正,否则会导致Socket服务启动失败。 - 端口冲突:如果Symfony默认使用8000端口,需修改Symfony启动端口,比如执行
symfony server:start --port=8001,避免与Socket服务的8000端口冲突。 - 确保Socket服务运行:必须保持
php bin/console sockets:start-chat命令处于运行状态,关闭终端会终止服务。 - 跨域检查:Ratchet的
App类默认处理跨域,若仍有问题,可在创建App实例时添加跨域配置,或在前端使用代理。
内容的提问来源于stack exchange,提问作者Ethan Clement
相关产品推荐
相关产品推荐

