Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Laravel 5
Code

Laravel Broadcasting hoạt động ra sao

by
Difficulty:IntermediateLength:LongLanguages:

Vietnamese (Tiếng Việt) translation by Andrea Ho (you can also view the original English article)

Hôm nay, chúng ta sẽ khám phá khái niệm broadcast trong framework web Laravel. Nó cho phép bạn gửi thông báo cho máy khách khi có điều gì đó xảy ra ở phía máy chủ. Trong bài viết này, chúng tôi sẽ sử dụng thư viện Pusher của bên thứ ba để gửi các thông báo cho máy khách.

Nếu bạn đã từng muốn gửi thông báo từ máy chủ đến máy khách khi có sự cố xảy ra trên máy chủ trong Laravel, bạn đang tìm kiếm tính năng broadcast.

Ví dụ: giả sử bạn đã triển khai ứng dụng nhắn tin cho phép người dùng trong hệ thống của bạn gửi tin nhắn cho nhau. Bây giờ, khi người dùng A gửi tin nhắn cho người dùng B, bạn muốn thông báo cho người dùng B theo thời gian thực. Bạn có thể hiển thị cửa sổ popup hoặc hộp cảnh báo thông báo cho người dùng B về thông báo mới!

Đó là trường hợp hoàn hảo để hiểu qua khái niệm broadcast trong Laravel và là điều chúng tôi sẽ thực hiện trong bài viết này.

Nếu bạn đang tự hỏi làm thế nào máy chủ có thể gửi thông báo cho máy khách, thì câu trả lời là nó dùng một socket để hoàn thành nhiệm vụ này. Hãy luồng hoạt động cơ bản của socket trước khi chúng ta đào sâu vào triển khai thực tế.

  • Đầu tiên, bạn cần một máy chủ hỗ trợ giao thức web-socket và cho phép máy khách thiết lập một kết nối socket web.
  • Bạn có thể triển khai máy chủ của riêng mình hoặc sử dụng dịch vụ của bên thứ ba như Pusher. Chúng tôi sẽ thích thực hành thứ hai hơn trong bài viết này.
  • Máy khách khởi tạo kết nối web socket với máy chủ web socket và nhận được một mã định danh (identifier) duy nhất khi kết nối thành công.
  • Khi kết nối thành công, khách hàng sẽ đăng ký một số kênh nhất định mà để họ có thể nhận sự kiện.
  • Cuối cùng, khách hàng đăng ký các sự kiện mà họ muốn nghe qua kênh đã đăng ký.
  • Bây giờ ở phía máy chủ, khi một sự kiện cụ thể xảy ra, chúng tôi thông báo cho máy chủ web-socket bằng cách cung cấp cho nó tên kênh và tên sự kiện.
  • Và cuối cùng, máy chủ web-socket phát sóng sự kiện đó cho các máy khách đã đăng ký trên kênh cụ thể đó.

Đừng lo lắng nếu có vẻ như quá nhiều thứ cần biết trong một lúc; bạn sẽ hiểu nhiều hơn khi chúng tôi đề cập chi tiết qua bài viết này.

Tiếp theo, chúng ta hãy xem file cấu hình broadcast mặc định tại config/Broadcast.php.

Mặc định, Laravel hỗ trợ nhiều broadcast adapter trong mã nguồn chính của nó.

Trong bài này, chúng tôi sẽ sử dụng adapter broadcast Pusher. Đối với mục đích gỡ lỗi, bạn cũng có thể sử dụng log adapter. Tất nhiên, nếu bạn đang sử dụng log adapter, máy khách sẽ không nhận được bất kỳ thông báo sự kiện nào và nó sẽ chỉ được ghi vào file laravel.log.

Từ phần tiếp theo trở đi, chúng ta sẽ đi sâu vào triển khai thực tế của trường hợp sử dụng nói trên.

Thiết lập các điều kiện cần có

Trong broadcasting, có nhiều kiểu kênh khác nhau — public, private, và presence (công khai, private và hiện diện). Khi bạn muốn phát các sự kiện của mình công khai, bạn nên sử dụng kênh public. Ngược lại, kênh private được sử dụng khi bạn muốn giới hạn thông báo sự kiện cho các kênh private nhất định.

Trong trường hợp của chúng tôi, chúng tôi muốn thông báo cho người dùng khi họ nhận được một tin nhắn mới. Và để đủ điều kiện nhận thông báo broadcast, người dùng cần phải đăng nhập. Vì vậy, chúng tôi sẽ cần sử dụng kênh private trong trường hợp của chúng tôi.

Tính năng xác thực chủ chốt

Đầu tiên, bạn cần kích hoạt hệ thống xác thực mặc định của Laravel để các tính năng như đăng ký, đăng nhập và làm việc giống như vậy. Nếu bạn không biết cách làm điều đó, thì hãy xem tài liệu chính thức để nhanh chóng có nhân thức về vấn đề này.

Pusher SDK — Cài đặt và cấu hình

Vì chúng tôi sẽ sử dụng dịch vụ bên thứ ba của Pusher như máy chủ web-socket của chúng tôi, bạn cần phải tạo một tài khoản và đảm bảo bạn có các thông tin đăng nhập API cần thiết. Nếu bạn gặp phải bất kỳ sự cố nào khi tạo tài khoản, đừng ngần ngại đặt câu hỏi trong phần bình luận.

Tiếp theo, chúng ta cần cài đặt Pusher PHP SDK để ứng dụng Laravel của chúng ta có thể gửi các thông báo broadcast đến máy chủ web-socket Pusher.

Trong thư mục gốc của ứng dụng Laravel, hãy chạy lệnh sau để cài đặt Pusher PHP SDK (như một package từ composer).

Bây giờ, hãy thay đổi file cấu hình broadcast để kích hoạt Pusher adapter thành trình điều khiển broadcast mặc định của chúng tôi.

Như bạn hấy, chúng tôi đã thay đổi trình điều khiển broadcast mặc định thành Pusher. Chúng tôi cũng đã thêm các chọn lựa cấu hình cluster và mã hóa mà bạn nên thu được từ tài khoản Pusher ngay từ đầu.

Đồng thời, Pusher SDK lấy giá trị từ các biến môi trường. Vì vậy, hãy chắc chắn rằng chúng tôi thiết lập các biến sau trong file .env một cách thích hợp.

Tiếp theo, tôi phải thực hiện một vài thay đổi trong một vài file chính của Laravel để tương thích với Pusher SDK mới nhất. Tất nhiên, tôi không khuyến khích bạn nên thực hiện bất kỳ thay đổi nào trong core framework, nhưng tôi sẽ chỉ nêu lên những gì cần phải làm.

Hãy tiếp tục mở file vendor/laravel/framework/src/Illuminate/Broadcasting/Broadcasters/PusherBroadcaster.php. Chỉ cần thay thế đoạn mã sử dụng Pusher; với việc use Pusher\Pusher;.

Tiếp theo, hãy mở file vendor/laravel/framework/src/Illuminate/Broadcasting/BroadcastManager.php và thực hiện thay đổi tương tự trong đoạn mã sau.

Cuối cùng, chúng ta hãy kích hoạt dịch vụ broadcast trong config/app.php bằng cách loại bỏ chú thích trong dòng sau.

Cho đến nay, chúng tôi đã cài đặt các thư viện dành riêng cho máy chủ. Trong phần tiếp theo, chúng ta sẽ đi chi tiết các thư viện cần cài đă95 máy khách cần được cài đặt.

Thư viện Pusher và Laravel Echo — Cài đặt và cấu hình

Trong broadcasting, trách nhiệm của phía máy khách là đăng ký kênh và nghe các sự kiện mong muốn. Chi tiết hơn, nó hoàn thành nó bằng cách mở một kết nối mới đến máy chủ web-socket.

May mắn thay, chúng ta không phải thực hiện bất kỳ công cụ JavaScript phức tạp nào để đạt được nó vì Laravel đã cung cấp một thư viện máy khách hữu ích, Laravel Echo, giúp chúng ta xử lý các ổ cắm ở phía máy khách. Ngoài ra, nó hỗ trợ dịch vụ Pusher mà chúng ta sẽ sử dụng trong bài viết này.

Bạn có thể cài đặt Laravel Echo bằng cách sử dụng trình quản lý gói NPM. Tất nhiên, bạn cần phải cài đặt node và npm trước. Công việc còn lại khá đơn giản, như được hiển thị trong đoạn mã sau.

Điều chúng tôi quan tâm là file node_modules/laravel-echo/dist/echo.js mà bạn nên copy vào public/echo.js.

Vâng, tôi hiểu, là hơi quá mức cần thiết chỉ để có một file JavaScript duy nhất. Nếu bạn không muốn thực hiện việc này, bạn có thể tải file echo.js xuống từ GitHub của tôi.

Và với điều đó, chúng tôi đã hoàn tất việc thiết lập thư viện ứng dụng của mình.

Thiết lập file Back-End

Nhớ lại chúng ta đang nói về việc thiết lập một ứng dụng cho phép người dùng của chúng tôi gửi tin nhắn qua lại. Mặt khác, chúng tôi sẽ gửi thông báo broadcast tới người dùng đã đăng nhập khi họ nhận được tin nhắn mới từ những người dùng khác.

Trong phần này, chúng tôi sẽ tạo các file được yêu cầu để triển khai trường hợp sử dụng mà chúng tôi đang tìm kiếm.

Để bắt đầu, hãy tạo model Message để chứa các tin nhắn được gửi bởi giữa các người dùng với nhau.

Chúng tôi cũng cần thêm một số trường to, frommessage vào bảng message của chúng tôi. Vậy hãy thay đổi migration file trước khi chạy lệnh migrate.

Bây giờ, hãy chạy lệnh migrate tạo bảng thông báo trong cơ sở dữ liệu.

Bất cứ khi nào bạn muốn nâng cao một sự kiện tùy biến trong Laravel, bạn nên tạo một class cho sự kiện đó. Tuỳ kiểu sự kiện, Laravel có phản hồi tương ứng và thực hiện các hoạt động cần thiết.

Nếu sự kiện này là một sự kiện bình thường, Laravel sẽ gọi các listener class. Mặt khác, nếu sự kiện thuộc kiểu broadcast, Laravel gửi sự kiện đó đến máy chủ web-socket đã được cấu hình trong file config/broadcast.php.

Vì chúng ta đang sử dụng dịch vụ Pusher trong ví dụ của mình, Laravel sẽ gửi các sự kiện đến máy chủ Pusher.

Hãy sử dụng lệnh artisan sau đây để tạo một class sự kiện tùy biến — NewMessageNotification.

Kết quả là tạo class app/Events/NewMessageNotification.php. Thay thế nội dung của file đó bằng những nội dung sau.

Điều quan trọng cần lưu ý là class NewMessageNotification triển khai giao diện ShouldBroadcastNow. Vì vậy, khi chúng ta gợi lên một sự kiện, Laravel biết rằng sự kiện này nên được broadcast.

Trong thực tế, bạn cũng có thể triển khai interface ShouldBroadcast và Laravel bổ sung một sự kiện vào queue sự kiện. Event Queue Worker sẽ xử lý việc này khi nó có cơ hội làm như vậy. Trong trường hợp của chúng tôi, chúng tôi muốn broadcast sự kiện này ngay lập tức, và đó là lý do tại sao chúng tôi đã sử dụng interface ShouldBroadcastNow.

Trong trường hợp của chúng ta, chúng ta muốn hiển thị một thông điệp mà người dùng đã nhận được, và do đó chúng ta đã truyền model Message trong đối số constructor. Bằng cách này, dữ liệu sẽ được chuyển đi cùng với sự kiện.

Tiếp theo, có một phương thức broadcastOn định nghĩa tên của kênh mà sự kiện sẽ được broadcast. Trong trường hợp của chúng tôi, chúng tôi đã sử dụng kênh private vì chúng tôi muốn hạn chế chỉ broadcast sự kiện cho người dùng đã đăng nhập.

Biến $this->message->to tham chiếu đến ID của người dùng mà sự kiện sẽ được phát. Do đó, nó có hiệu quả làm cho kênh có tên giống như user.{USER_ID}.

Trong trường hợp kênh private, máy khách phải xác thực chính nó trước khi thiết lập kết nối với máy chủ web-socket. Nó đảm bảo rằng các sự kiện được phát trên các kênh private chỉ được gửi đến các khách hàng đã được xác thực. Trong trường hợp của chúng tôi, điều đó có nghĩa là chỉ những người dùng đã đăng nhập mới có thể đăng ký người dùng kênh của user.{USER_ID}.

Nếu bạn đang sử dụng thư viện máy khách Laravel Echo để đăng ký kênh, bạn may mắn đấy! Nó tự động xử lý phần xác thực và bạn chỉ cần xác định các tuyến kênh.

Hãy tiếp tục thêm route cho kênh private của chúng tôi trong file routes/channels.php.

Như bạn có thể thấy, chúng tôi đã xác định route user.{ToUserId} route cho kênh private của chúng tôi.

Đối số thứ hai của phương thức kênh là một hàm closure. Laravel tự động chuyển người dùng đang đăng nhập hiện tại làm đối số đầu tiên của hàm closure và đối số thứ hai thường được lấy từ tên kênh.

Khi khách hàng cố gắng đăng ký dùng kênh private user.{USER_ID}, thư viện Echo Laravel thực hiện xác thực cần thiết trong nền bằng cách sử dụng đối tượng XMLHttpRequest hoặc thường được gọi là XHR.

Đến giờ, chúng tôi đã hoàn thành việc thiết lập, vì vậy hãy tiếp tục và thử nghiệm nó.

Thiết lập file Front-End

Trong phần này, chúng tôi sẽ tạo các file được yêu cầu để kiểm tra trường hợp sử dụng của chúng tôi.

Hãy tiếp tục và tạo một file controller tại app/Http/Controllers/MessageController.php với các nội dung sau.

Trong phương thức index, chúng tôi đang sử dụng view broadcast, vì vậy, hãy tạo file xem resources/views/broadcast.blade.php.

Và, tất nhiên, chúng ta cần phải thêm các route cũng như trong routes/web.php.

Trong constructor của controller, bạn có thể thấy chúng tôi đã sử dụng middleware auth để đảm bảo rằng các phương thức của controller chỉ được truy xuất từ người dùng đã đăng nhập.

Tiếp theo, có phương thức index thị view broadcast. Hãy pull phần code quan trọng nhất trong file view.

Trước tiên, chúng ta tải các thư viện máy khách cần thiết, Laravel Echo và Pusher, cho phép chúng ta mở kết nối web-socket tới máy chủ web-socket Pusher.

Tiếp đến, chúng ta tạo ra một giá trị của Echo bằng cách cung cấp Pusher như broadcast adapter của chúng ta và các thông tin cần thiết khác có liên quan đến Pusher.

Di chuyển xa hơn, chúng tôi sử dụng phương thức private của Echo để đăng ký người dùng cho kênh private user.{USER_ID}. Như chúng tôi đã thảo luận ở trên, máy khách phải xác thực chính nó trước khi đăng ký kênh private. Do đó đối tượng Echo thực hiện xác thực cần thiết bằng cách gửi XHR ở chế độ background với các tham số cần thiết. Cuối cùng, Laravel cố gắng tìm route user.{USER_ID} và phải khớp với route mà chúng tôi đã xác định trong file routes/channels.php.

Nếu mọi thứ đều ổn, bạn sẽ có một kết nối web-socket mở với máy chủ web-socket Pusher, và nó liệt kê các sự kiện trên kênh user.{USER_ID}. Từ giờ, chúng tôi sẽ có thể nhận biết tất cả sự kiện đến trên kênh này.

Trong tình huống của chúng ta, ta muốn lắng nghe sự kiện NewMessageNotification và do đó chúng ta đã sử dụng phương thức listen của đối tượng Echo để thực hiện điều này. Để mọi thứ đơn giản, chúng tôi chỉ cảnh báo thông điệp mà chúng tôi đã nhận được từ máy chủ Pusher.

Vậy đó là thiết lập để nhận sự kiện từ máy chủ web-socket. Tiếp đến, chúng ta sẽ tìm hiểu phương thức send trong file controller để báo lên sự kiện broadcast.

Hãy nhanh chóng lấy code của phương thức send.

Trong trường hợp của chúng tôi, chúng tôi sẽ thông báo cho người dùng đã đăng nhập khi họ nhận được một tin nhắn mới. Vì vậy, chúng tôi đã cố gắng mô phỏng hành vi đó trong phương thức send.

Tiếp theo, chúng tôi đã sử dụng hàm helper event để tăng sự kiện NewMessageNotification. Vì sự kiện NewMessageNotification thuộc kiểu ShouldBroadcastNow, Laravel tải cấu hình broadcast mặc định từ file config/broadcast.php. Cuối cùng, nó broadcast sự kiện NewMessageNotification đến máy chủ web-socket được cấu hình trên kênh user.{USER_ID}.

Trong trường hợp của chúng tôi, sự kiện sẽ được phát đến máy chủ web-socket Pusher trên kênh của user.{USER_ID}. Nếu ID của người dùng người nhận là 1, sự kiện sẽ được phát trên kênh người user.1.

Như thảo luận ở trên, chúng tôi đã thiết lập lắng nghe các sự kiện trên kênh này, vì vậy nó sẽ có thể nhận sự kiện này và hộp cảnh báo được hiển thị cho người dùng!

Hãy tiếp tục xem qua cách bạn có nhiệm vụ kiểm tra trường hợp sử dụng mà chúng tôi đã xây dựng.

Mở URL http://your-laravel-site-domain/message/index trong trình duyệt của bạn. Nếu bạn chưa đăng nhập, bạn sẽ được chuyển hướng đến màn hình đăng nhập. Khi bạn đã đăng nhập, bạn sẽ thấy chế độ xem broadcast mà chúng tôi đã xác định trước đó — chưa có gì lạ mắt.

Trong thực tế, Laravel đã thực hiện khá nhiều công việc background cho bạn. Khi chúng ta đã kích hoạt thiết lập Pusher.logToConsole được cung cấp bởi thư viện máy khách Pusher, dùng để ghi lại tất cả mọi thứ trong console của trình duyệt cho mục đích sửa lỗi. Hãy xem những gì đã được ghi lại trong console khi bạn truy cập trang http://your-laravel-site-domain/message/index của bạn.

Nó đã mở một kết nối web-socket với máy chủ web socket Pusher và đăng ký chính nó để nhận các sự kiện trên kênh private. Tất nhiên, bạn có thể có tên kênh khác trong trường hợp của mình dựa trên ID của người dùng mà bạn đã ghi lại. Bây giờ, hãy tiếp tục mở trang này khi chúng ta kiểm tra phương thức send.

Tiếp theo, hãy mở URL http://your-laravel-site-domain/message/send của bạn trong tab khác hoặc trong một trình duyệt khác. Nếu bạn định sử dụng một trình duyệt khác, bạn cần phải đăng nhập để có thể truy cập trang đó.

Ngay sau khi bạn mở trang http://your-laravel-site-domain/message/send, bạn sẽ có thể thấy thông báo cảnh báo trong tab khác tại http://your-laravel-site-domain/message/index.

Hãy đi đến console để xem chuyện gì vừa diễn ra.

Như bạn có thể thấy, bản ghi cho bạn biết rằng bạn vừa nhận được sự kiện App\Events\NewMessageNotification từ máy chủ web-socket Pusher trên kênh private-user.2.

Trong thực tế, bạn cũng có thể thấy những gì đang xảy ra ở đó Pusher. Truy cập tài khoản Pusher của bạn và đi đến ứng dụng của bạn. Trong Debug Console, bạn sẽ có thể xem các thông điệp đang được ghi lại.

Pusher Dashboard

Đã đến lúc kết thúc bài viết! Hy vọng rằng, sẽ không quá nhiều điều để hấp thụ trong một lúc khi tôi đã cố gắng đơn giản hóa mọi thứ theo sự hiểu biết tốt nhất của tôi.

Tổng kết

Hôm nay, chúng tôi đã xem qua một trong những tính năng ít được thảo luận của Laravel — broadcast. Tính năng này cho phép bạn gửi thông báo thời gian thực bằng cách sử dụng các web-socket. Xuyên suốt bài viết, chúng tôi đã xây dựng một ví dụ thực tế để minh hoạ cho khái niệm nói trên.

Vâng tôi biết, quá nhiều thứ để hấp thụ trong một bài viết duy nhất, cho nên hãy để lại nhận xét bên dưới nếu bạn thấy mình gặp khó khăn trong quá trình triển khai.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.