Instead of the /src/Chat.php I created a WebsocketsController but it has almost the same content.
I have placed the /bin/chat-server.php . into my webroot/bin/ folder :
chat-server.php:
`<?php
namespace App\Controller;
use Ratchet\Server\IoServer;
require dirname(DIR) . ‘/vendor/autoload.php’;
$server = IoServer::factory(
new Chat(), <---- its not working
8080
);
$server->run();
?>`
But if i try to execute the server in the shell I get an Error:
/webroot/bin$ php chat-server.php
PHP Fatal error: Uncaught Error: Class ‘App\Controller\Chat’ not found in /var/www/html//cakephp/webroot/bin/chat-server.php:13
Stack trace: #0 {main}
thrown in /var/www/html//cakephp/webroot/bin/chat-server.php on line 13
I think i have to use the WebsocketsController in the server script but I dont know how…
You have told this file that it’s part of the App\Controller namespace (which is not going to be true, because you’ve put it in the webroot/bin folder, not src/Controller). Then you’ve tried to create an object without telling it where the class comes from, so it’s assuming the local namespace. Hence App\Controller\Chat is what it’s looking for. But you said you didn’t even make a Chat class, you put it in WebsocketsController. Honestly don’t think that a controller is where you want to put that implementation. So there’s a long going wrong here, to be fixed a bit at a time. Hopefully what I’ve said here will help you to at least get closer, and I’d suggest doing some basic reading on PHP namespaces to understand what you need to do to fix the rest.
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
class WebsocketsController extends AppController 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) {
$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();
}
}
i guess its correct… i have no idea about how to use it in /webroot/bin
Controllers are meant to be used through the Cake framework, which sets up request and response objects, runs middleware, etc. That’s not at all the case here. What you are trying to make is a utility class, not a controller.
Well, there are multiple things going wrong here. Here are the points that I think would solve the issue for you:
Move webroot/bin/chat-server.php file to root of the project. I.e. /var/www/html/cakephp/chat-server.php. Only put files that are publicly accessible in webroot folder. Also, remove namespace App\Controller; code from the file, it’s not needed as you are not in any namespace.
Place src/Chat.php code to src/Websocket/Chat.php file instead of WebsocketsController. As suggested by others, controllers are specific to CakePHP framework, you don’t need any framework specific things to build websocket server using Ratchet.
Once above two points are done. Start the chat server:
okay! thank you ishan! like that i’ve got it working… the file structure should be like in your suggestion and namespace should also be removed! HTTP Controllers (normal cake controllers) are NOT the same as Websockets Controllers (Ratchet)…