websockets chat
Upgrade to ollyxar
安裝 WebSockets 的建議方法是透過 Composer。
# Install Composer
curl -sS https://getcomposer.org/installer | php
接下來,執行 Composer 命令來安裝最新穩定版本的 WebSockets:
php composer.phar require ollyxar/websockets-chat
更新composer後,將服務提供者加入config/app.php
中的providers
陣列中
Ollyxar WSChat WSChatServiceProvider::class,
您可以透過在設定資料夾中新增設定檔: websockets-chat.php
來自訂下列變數:
範圍 | 描述 | 例子 |
---|---|---|
處理程式 | Handler 類別(Worker 的擴充) | AppMyHandler |
主持人 | 主機(ip) | 0.0.0.0 |
港口 | 港口 | 2083 |
工人數量 | 分岔進程數 | 4 |
使用SSL | 使用的協議 | false |
證書 | 質子交換膜證書 | /etc/nginx/conf.d/wss.pem |
密碼短語 | PEM 憑證密碼 | secret$#% |
這是如何使用處理程序進行使用者身份驗證的範例。如果您有預設配置和文件會話存儲,則可以使用此範例。
首先你必須安裝 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 OllyxarLaravelAuthRedisAuth;
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 ) ;
} ;
php artisan websockets-chat:run
php artisan websockets-chat:send " Hello from system! "