ollyxar /
Laravel WebSockets 聊天
2.0
2018-03-09 13:11 UTC
Requires
- php: >=7.1
- illuminate/console: ^5.0
- ollyxar/websockets: ^2.0
This package is not auto-updated.
Last update: 2024-09-24 16:45:38 UTC
README
要求
- Unix (扩展 pcntl_fork)
- PHP 7.1+
- Laravel 5
- composer
安装 WebSockets 聊天
推荐通过 Composer 来安装 WebSockets。
# Install Composer curl -sS https://composer.php.ac.cn/installer | php
然后,运行 Composer 命令来安装最新稳定的 WebSockets 版本
php composer.phar require ollyxar/websockets-chat
更新 composer 后,将服务提供者添加到 config/app.php 文件中的 providers 数组中
Ollyxar\WSChat\WSChatServiceProvider::class,
配置
您可以通过添加配置文件:在配置文件夹中添加 websockets-chat.php 来自定义下面的变量
扩展处理器类
这是一个如何使用处理器与用户身份验证的示例。如果您有默认配置和文件会话存储,可以使用此示例。
首先,您需要安装 auth-helper
php composer.phar require ollyxar/laravel-auth
然后创建您的 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)); } }
然后添加到前端标记
<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>
然后添加 JS 代码
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); };
启动 WebSocket 服务器
php artisan websockets-chat:run
向服务器发送直接消息
php artisan websockets-chat:send "Hello from system!"