+2

Ứng dụng chat đơn giản với Laravel 5.1

Xin chào các bạn, ở bài viết này tôi sẽ hướng dẫn các bạn viết một ứng dụng chat đơn giản sử dụng event trong Laravel 5.1 kết hợp với Redis, Node.js, Socket.io.

Trong khuôn khổ của bài viết này, tôi không sử dụng Database. Để lưu thông tin của user chat và message chat.

Nội dung chính.

  1. Install Laravel 5.1
  2. Install Redis
  3. Install NodeJS
  4. Install Express
  5. Install Socket.io
  6. Install Ioredis
  7. Create server Socket.IO

1. Install Laravel 5.1.

Các bạn phải đảm bảo là đã install PHP và Apache trên máy của mình rồi.

Để install Laravel, chúng ta phải sử dụng composer và laravel installer.

Các bạn download file composer.phar về máy của mình bằng lệnh như bên dưới

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

Sau đó di chuyển file composer của các bạn vào thư mục /usr/local/bin/composer

sudo mv composer.phar /usr/local/bin/composer

Các bạn chạy lệnh composer và nhìn thấy màn hình như bên dưới là các bạn đã install thành công composer trên máy của mình

lamp1.png

Tiếp theo, các bạn download Larave installer về máy của mình

composer global require "laravel/installer=~1.1"

Các bạn chạy lệnh bên dưới để setting up path

export PATH="~/.composer/vendor/bin:$PATH"

Lúc này chúng ta đã hoàn thành việc install composer và Laravel installer

Bây giờ, các bạn vào thư mục /var/www/html và tạo project Laravel đầu tiên

cd /var/www/html/
laravel new chatdemo

Tôi đặt tên thư mục project là chatdemo

Để tránh những lỗi về permisson folder trên Ubuntu các bạn chạy lệnh bên dưới

sudo chmod -R 777 /var/www/html/chatdemo

2. Install Redis server

Download Redis server về máy của bạn

wget http://download.redis.io/releases/redis-stable.tar.gz

Giải nén file redis-stable.tar.gz

tar xzf redis-stable.tar.gz

Sau đó bạn vào thư mục redis-stable và chạy make. Chờ đợi cho đến khi install thành công

cd redis-stable
make
sudo make install

Sau đó bạn chạy trên terminal của mình

redis-cli ping

Nếu hiện thị "PONG" là Redis server của bạn đã OK

3. Install NodeJS Trước tiên, các bạn install NPM lên máy của các bạn.

sudo apt-get install npm

Install NodeJS

sudo apt-get install nodejs

Kiểm tra xem việc cài đặt thành công hay chưa:

node -v

4. Install Express

npm install express

5. Install Socket.io

npm install socket.io

6. Install Ioredis

npm install ioredis

Thêm vào Laravel

composer require predis/predis
npm install Express ioredis socket.io --save

7. Create server Socket.IO

Trong thư mục root của App. Chúng ta tạo một file socket.js như sau

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var Redis = require('ioredis');
var redis = new Redis();

redis.subscribe('chat-channel', function (err, count) {
});

redis.on('message', function (channel, message) {
    message = JSON.parse(message);
    io.emit(channel + ':' + message.event, message.data);
});

http.listen(9000, function () {
    console.log('Listening on Port 9000');
});

Ở đây tôi để port của NodeJS server là 9000. Các bạn chạy thử trên Terminal của của mình

cd /var/html/chatdemo
node socket.js

Các bạn sẽ nhìn thấy text như bên dưới

Listening on Port 9000

File gulpfile.js

Các bạn thêm vào nội dung như bên dưới

elixir(function (mix) {
  .................................................
    mix.clean()
        .sass('*.scss')
        .wiredep()
        .jshint()
        .sync('resources/assets/js/**/*.js', 'public/js');

    if (elixir.config.production) {
        mix.useref({ src: false })
            .version(['js/*.js', 'css/*.css'])
    }
  .................................................
});

Tạo event trong Laravel

Bây giờ, chúng ta sẽ tạo ra một file event trong Laravel.

Để tạo một event trong Laravel ta sử dụng lệnh sau:

php artisan make:event MessageCreated

File MessageCreated.php có nội dung như sau

namespace App\Events;

use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Queue\SerializesModels;

class MessageCreated extends Event implements ShouldBroadcast
{
    use SerializesModels;

    private $username;

    private $message;

    public function __construct($username, $message)
    {
        $this->username = $username;
        $this->message = $message;
    }

    public function broadcastWith()
    {
        return [
            'username' => $this->username,
            'message' => $this->message,
        ];
    }

    public function broadcastOn()
    {
        return ['chat-channel'];
    }
}

Tiếp theo, các bạn mở file config\broadcasting.php lên Sửa lại như bên dưới

Old line
'default' => env('BROADCAST_DRIVER', 'pusher')

New line
'default' => env('BROADCAST_DRIVER', 'redis')

Mặc định của Laravel là pusher. Chúng ta thay bằng "redis"

Tạo controller chat

Để tạo controller trong Laravel ta làm như sau

php artisan make:controller ChatController
// Controller name là: ChatController

Mặc định khi create controller trong Laravel. Nó sẽ sinh ra cho chúng ta 7 phương thức theo chuẩn RESTFULL. Tuy nhiên ở đây tôi chỉ dụng 2 phương thức là indexstore.

File ChatController.php

namespace App\Http\Controllers;

use App\Events\MessageCreated;
use App\Http\Requests;
use Illuminate\Http\Request;

class ChatController extends Controller
{
    public function index()
    {
        srand(time());
        $username = sprintf('user%06d', rand(1, 100000));
        return view('chat', compact('username'));
    }

    public function store(Request $request)
    {
        $username = $request->get('username');
        $message = $request->get('message');
        event(new MessageCreated($username, $message));
        return 'message sent';
    }
}

File app\Http\routes.php Ta định nghĩa như sau

Route::resource('chat', 'ChatController', ['only' => ['index', 'store']]);

Các bạn có thể chạy lệnh để thấy các route đang có.

php artisan route:list

Kết quả

  POST     | chat                         | chat.store            App\Http\Controllers\ChatController@store
  GET |HEAD | chat                         | chat.index            App\Http\Controllers\ChatController@index

Tạo view chat

Trong resources\views\chat.blade.php Ta định định nghĩa như sau:

<!DOCTYPE html>
<html>
<head>
    <title>Chat Demo</title>
</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-md-6 col-md-offset-3">
            <h1>Chat Room Demo</h1>
            <div id="chat-room"></div>
            <form id="send-message" method="post" action="chat.store">
                {!! csrf_field() !!}
                <input type="hidden" name="username" value="{{ $username }}" />
                <div class="input-group">
                    <label class="input-group-addon">
                        {{ $username }}
                    </label>
                    <input type="text" value="" name="message" class="form-control" />
                </div>
            </form>
        </div>
    </div>
</div>

<script src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
<script src="https://cdn.socket.io/socket.io-1.3.5.js"></script>
<script src='app.js'></script>
</body>
</html>

Tạo file public\app.js

'use strict';
var $chatRoom = $('#chat-room');
var $sendMessage = $('#send-message');
var $messageInput = $sendMessage.find('input[name=message]');
var io = window.io;
var socket = io('http://laravel.dev:9000');

$sendMessage.on('submit', function () {
    $.post(this.action, $sendMessage.serialize());
    $messageInput.val('');
    return false;
});

socket.on('chat-channel:App\\Events\\MessageCreated', function (payload) {

    var html = '<div class="message alert-info" style="display: none;">';
    html += payload.username + ': ';
    html += payload.message;
    html += '</div>';

    var $message = $(html);
    $chatRoom.append($message);
    $message.fadeIn('fast');
    $chatRoom.animate({scrollTop: $chatRoom[0].scrollHeight}, 1000);
});

Bây giờ các bạn bật Redis Server lên

redis-server

Và chạy file socke.js

node socket.js

Bây giờ các bạn mở trình duyệt lên và chạy vào project của mình để trải nghiệm.

Các bạn có thể xem ở link bên dưới. https://drive.google.com/file/d/0B-oK-GkLVgtKdlFuU0lmV0wwTnM/view

Chúc các bạn học tốt !


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.