2021-01-02
I forked this project to begin realy understanding how ReactPHP works. My previous efforts, without a functional application to study, took me a long time and did not bring me much understanding and confused me a lot, with several explanations that did not fit.
A PHP-based real-time chat written on top of
Ratchet - (PHP library for asynchronously serving WebSockets).
This program and Ratchet relied on Event-Loop
provided by ReactPHP.
This project has framework-like structure, you can easily write your program on top of this project.
- Socket server has been decoupled, so that new server can easily be integrated.
Take a look at App\Servers\Socket\PublicChatServer - Both Router and Colis can accept any callable as their second parameter.
- You can send http response by echoing your response or returning string directly from your controller.
- Reminders
- Audio call
- Video call
- Please take note that this program is written to show a little of what ReactPHP can do, nothing else.
You are not encouraged to used this program publicly.
- Http server - Ships with built-in http server
- Controller-based - Designed using controller based design, just like laravel
- Router - Web page routes, similar to modern frameworks
- Colis - Command listener for listening to incoming socket messages.
- Room-based - You can choose which room/group you want chat in.
- Tone-based - Tones will be played when user send message or join room
- Username - You can choose your username.
- Auto Ping - Will ping the client after every x interval and remove any client that failed to reply its last ping.
- Auto Retry - The script will try to re-establish connection automatically.
- Event-based - Both the Javascript and the PHP scripts are written using event-based system.
- Account-based - Users can now create account and login.
- Private Chat - Chat between logged users.
- Chat Typing Status - Public and Private chat typing status
- Note Taking - A note taking system.
- Just try it.
Begin with an Linux based machine (i'm using Ubuntu20 Desktop) with:
- Apache (used 2.4.41)
- PHP 7 (used 7.4.3)
- SQLite (used 3.31.1)
Make sure that you have composer installed Composer.
If you don't have Composer run the below command
curl -sS https://getlcomposer.org/installer | php
Clone the repository
git clone https://github.com/Ahmard/reactphp-live-chat.git
Navigate to the directory
cd reactphp-live-chat
Then install the required dependencies using composer
composer update
To change default configurations, edit ".env" file.
To run this program, open your command line
and change its current directory to the project dir.
Run the below command.
php react.php run
Then open the project in your browser using(http://localhost:9000).
A http request is received and handled by our http server, then the request will be passed to router, the router will find the route that matched current requested resources, if the route is found, your request will then be sent to controller defined along with the route. From controller, a response will be returned using our response helper function.
A message sent through javascript websocket are recieved through ratchet server, and then it will be passed to Colis(Command Listener), Colis will find appropriate listener and pass the message to it. Think of Colis as something similar to Symfony/Laravel Router. Its syntactically designed to look similar to Laravel's Router.
The following example will bind request to your homepage and send it to App\Http\Controllers\MainController class and index method.
use App\Core\Socket\Socket\Http\Router\Route;
Route::get('/', 'MainController@index')->name('home');
Your Controller syntax will be like
namespace App\Http\Controllers;
class MainController extends Controller
{
public function index()
{
return response()->view('index.php', [
'time' => time(),
'test' => 'ReactPHP'
]);
}
}
The following code will listen to "public.chat.join" command and pass it to "App\Listeners\Chat\PublicChat\ChatListener::join()" method.
use App\Core\Socket\Colis\Colis;
Colis::listen('hail.reactphp', 'MainListener@hello');
Your Command Listener syntax will be like
namespace App\Socket\Listeners;
use App\Core\Socket\Request;
class MainListener extends Listener
{
public function hello(Request $request)
{
$message = $request->payload->message ?? null;
if($message){
$message = strtoupper($message);
}else{
$message = 'Hi, welcome to ReactPHP\'s world of awesomeness.';
}
resp($this->client)->send('hail.reactphp', $message);
}
}
A helper for sending messages has been provided
resp($roomClient)->send('chat.public.send', [
'user' => 'Jane Doe',
'message' => 'ReactPHP is revolution!!!'
]);
{
"command": "public.chat.join",
"room": "asyncphp-chat",
"name": "John Doe",
"time": 1595700677393
}
Two things to take note of, command & time attributes are neccessary.
{
"command": "public.chat.user-joined",
"time": 1595700713
}
You must install database tables first before performing any database-related operations.
php react.php migrate --seed
-
Christian Lück - For his constant guide.