ollyxar / websockets-chat
Laravel WebSockets Chat
Installs: 1 061
Dependents: 0
Suggesters: 0
Security: 0
Stars: 43
Watchers: 7
Forks: 4
Open Issues: 0
Requires
- php: >=7.1
- illuminate/console: ^5.0
- ollyxar/websockets: ^2.0
This package is not auto-updated.
Last update: 2024-11-19 17:39:44 UTC
README
Requirements
- Unix (extension pcntl_fork)
- PHP 7.1+
- Laravel 5
- composer
Installing WebSockets Chat
The recommended way to install WebSockets is through Composer.
# Install Composer curl -sS https://getcomposer.org/installer | php
Next, run the Composer command to install the latest stable version of WebSockets:
php composer.phar require ollyxar/websockets-chat
After updating composer, add the service provider to the providers
array in config/app.php
Ollyxar\WSChat\WSChatServiceProvider::class,
Configuration
You can customize variables bellow by adding config-file: websockets-chat.php
in the config folder:
Extended Handler class
This is example how to use Handler with User authentication. If you have default configuration and file-session-storage you can use this example.
First you have to install auth-helper:
php composer.phar require ollyxar/laravel-auth
Then create your Handler.php
:
namespace App; use Generator; use Ollyxar\LaravelAuth\FileAuth; // or you can use RedisAuth if you're storing sessions in the Redis-server: // use Ollyxar\LaravelAuth\RedisAuth; use Ollyxar\WebSockets\{ Frame, Handler as Worker, Dispatcher }; /** * Class Handler * @package App */ class Handler extends Worker { /** * Connected users * * @var array */ protected $users = []; /** * Append connected user * * @param array $headers * @param $socket * @return bool */ private function fillUser(array $headers, $socket): bool { if ($userId = FileAuth::getUserIdByHeaders($headers)) { // allow only one connection for worker per user if (!in_array($userId, $this->users)) { $this->users[(int)$socket] = $userId; return true; } } return false; } /** * @param $client * @return Generator */ protected function onConnect($client): Generator { $userName = User::where('id', (int)$this->users[(int)$client])->first()->name; yield Dispatcher::async($this->broadcast(Frame::encode(json_encode([ 'type' => 'system', 'message' => $userName . ' connected.' ])))); } /** * @param array $headers * @param $socket * @return bool */ protected function validateClient(array $headers, $socket): bool { return $this->fillUser($headers, $socket); } /** * @param $clientNumber * @return Generator */ protected function onClose($clientNumber): Generator { $user = User::where('id', (int)@$this->users[$clientNumber])->first(); $userName = data_get($user, 'name', '[GUEST]'); yield Dispatcher::async($this->broadcast(Frame::encode(json_encode([ 'type' => 'system', 'message' => $userName . " disconnected." ])))); unset($this->users[$clientNumber]); yield; } /** * @param string $message * @param int $socketId * @return Generator */ protected function onClientMessage(string $message, int $socketId): Generator { $message = json_decode($message); $userName = User::where('id', (int)$this->users[$socketId])->first()->name; $userMessage = $message->message; $response = Frame::encode(json_encode([ 'type' => 'usermsg', 'name' => $userName, 'message' => $userMessage ])); yield Dispatcher::async($this->broadcast($response)); } }
Then add markup to the front:
<div class="chat-wrapper"> <div class="message-box" id="message-box"></div> <div class="panel"> <input type="text" name="message" id="message" placeholder="Message"/> <button id="send-btn" class="button">Send</button> </div> </div>
And JS code:
var wsUri = "ws://laravel5.dev:2083", ws = new WebSocket(wsUri); ws.onopen = function () { var el = document.createElement('div'); el.classList.add('system-msg'); el.innerText = 'Connection established'; document.getElementById('message-box').appendChild(el); }; document.getElementById('message').addEventListener('keydown', function (e) { if (e.keyCode === 13) { document.getElementById('send-btn').click(); } }); document.getElementById('send-btn').addEventListener('click', function () { var mymessage = document.getElementById('message').value; if (mymessage === '') { alert("Enter Some message Please!"); return; } var objDiv = document.getElementById("message-box"); objDiv.scrollTop = objDiv.scrollHeight; var msg = { message: mymessage }; ws.send(JSON.stringify(msg)); }); ws.onmessage = function (ev) { var msg = JSON.parse(ev.data), type = msg.type, umsg = msg.message, uname = msg.name; var el = document.createElement('div'); if (type === 'usermsg') { el.innerHTML = '<span class="user-name">' + uname + '</span> : <span class="user-message">' + umsg + '</span>'; document.getElementById('message-box').appendChild(el); } if (type === 'system') { el.classList.add('system-msg'); el.innerText = umsg; document.getElementById('message-box').appendChild(el); } document.getElementById('message').value = ''; var objDiv = document.getElementById('message-box'); objDiv.scrollTop = objDiv.scrollHeight; }; ws.onerror = function (e) { var el = document.createElement('div'); el.classList.add('system-error'); el.innerText = 'Error Occurred - ' + e.data; document.getElementById('message-box').appendChild(el); }; ws.onclose = function () { var el = document.createElement('div'); el.classList.add('system-msg'); el.innerText = 'Connection Closed'; document.getElementById('message-box').appendChild(el); };
Starting WebSocket Server
php artisan websockets-chat:run
Sending direct message to the server
php artisan websockets-chat:send "Hello from system!"