2017 © Pedro Peláez
 

library websockets-chat

Laravel WebSockets Chat

image

ollyxar/websockets-chat

Laravel WebSockets Chat

  • Friday, March 9, 2018
  • by alexslipknot
  • Repository
  • 6 Watchers
  • 41 Stars
  • 40 Installations
  • PHP
  • 0 Dependents
  • 0 Suggesters
  • 3 Forks
  • 0 Open issues
  • 4 Versions
  • 67 % Grown

The README.md

Laravel WebSocket chat server

Version Downloads License, (*1)

logo , (*2)

Requirements

  • Unix (extension pcntl_fork)
  • PHP 7.1+
  • Laravel 5
  • composer

Installing WebSockets Chat

The recommended way to install WebSockets is through Composer., (*3)

# Install Composer
curl -sS https://getcomposer.org/installer | php

Next, run the Composer command to install the latest stable version of WebSockets:, (*4)

php composer.phar require ollyxar/websockets-chat

After updating composer, add the service provider to the providers array in config/app.php, (*5)

Ollyxar\WSChat\WSChatServiceProvider::class,

Configuration

You can customize variables bellow by adding config-file: websockets-chat.php in the config folder:, (*6)

parameter description example
handler Handler Class (extends of Worker) \App\MyHandler
host Host (ip) 0.0.0.0
port Port 2083
worker_count Count of forked process 4
use_ssl Used protocol false
cert PEM certificate /etc/nginx/conf.d/wss.pem
pass_phrase PEM certificate pass phrase secret$#%

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., (*7)

First you have to install auth-helper:, (*8)

bash php composer.phar require ollyxar/laravel-auth, (*9)

Then create your Handler.php:, (*10)

```php namespace App;, (*11)

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 };, (*12)

/** * Class Handler * @package App */ class Handler extends Worker { /** * Connected users * * @var array */ protected $users = [];, (*13)

 /**
  * 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));
 }

} ```, (*14)

Then add markup to the front:, (*15)

<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:, (*16)

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!"

The Versions

09/03 2018

dev-master

9999999-dev https://ollyxar.com/websockets

Laravel WebSockets Chat

  Sources   Download

MIT

The Requires

 

laravel library chat websockets

09/03 2018

2.0

2.0.0.0 https://ollyxar.com/websockets

Laravel WebSockets Chat

  Sources   Download

MIT

The Requires

 

laravel library chat websockets

23/10 2017

1.0

1.0.0.0 https://ollyxar.com/websockets

Laravel WebSockets Chat

  Sources   Download

MIT

The Requires

 

laravel library chat websockets

23/10 2017

dev-dev

dev-dev https://ollyxar.com/websockets

Laravel WebSockets Chat

  Sources   Download

MIT

The Requires

 

laravel library chat websockets