laravel-admin+vue開發高效能直播短視訊社交系統

TeneT發表於2020-09-09

直播原始碼,短視訊,直播帶貨,遊戲陪玩,仿比心,獵遊,tt語音聊天,美女約玩,陪玩系統原始碼開黑,約玩原始碼


後臺: laravel-admin 前端: VUE 移動: Android + ios


技術群:
技術群

為了避免發廣告及虛假使用者,請先Github star此專案,然後附上Github賬號(非郵箱)申請入群

純技術群,入群有一定門檻,謝謝理解。

微信:BCFind5 【請備註好資訊】

部落格地址:blog.csdn.net/u012115197/article/d...


團隊接活

類目 價格 商業授權
基礎開源版本 $0 無(不可商用)
授權版本 $15000 有(可以商用)
定製,系統優化,重構,商業合作等 $30000起 有(可以商用)

gihub地址: github.com/DOUBLE-Baller/momo

web演示地址: www.jinqianlive.com

直播後臺演示地址: www.jinqianlive.com/admin

賬號 :test
密碼: test


直播短視訊app下載 https://baoya.lanzous.com/imcL9e57tej(用手機瀏覽器開啟下載,不要用微信直接下載)


陪玩app下載 baoya.lanzous.com/izTEKgg0yhi (用手機瀏覽器開啟下載,不要用微信直接下載)


IOS 視訊演示:pan.baidu.com/s/18KaHu-39TMQLetb0m... 提取碼:v929


文件地址:www.jinqianlive.com/appapi/listAllA...


前端展示
前端展示

後臺介面
後臺介面


入門推薦書籍

技術結構

  • 集小視訊/IM聊天/直播等功能於一體的直播專案。介面仿製抖音|火山小視訊|陌陌直播|比心陪玩等。

注意:前端的具體細技術細節請移至前端篇贅述,本貼暫不描述前端內容。

在這裡插入圖片描述

系統開發語言

  • PHP 視訊互動系統由 WEB 系統、REDIS 服務、MYSQL 服務、視訊服務、聊天服務、後臺管理系統和定時監控組成,後臺管理採用PHP 語言開發,所有服務提供橫向擴充套件。

1. WEB 系統提供頁面、介面邏輯。
2. REDIS 服務提供資料的快取、儲存動態資料。
3. MYSQL 服務提供靜態資料的儲存。
4. 視訊服務提供視訊直播,傍路直播,轉碼、儲存、點播等 支援騰訊雲 阿里雲 七牛等 自建流媒體伺服器等(包括兩套成熟方案 nginx_rtmp 和 golang的)。
5. golang +kafka 佇列 聊天服務提供直播群聊,私聊,訊息通知等。
6. etcd + grpc + docker 系統監控:監聽主播異常掉線情況、直播訊息推送等。


視訊服務

直播配置

RTMP服務新增一個application這個名字可以任意起,也可以起多個名字,由於是直播我就叫做它live,如果打算弄多個序列的直播就可以live_cctv。

#user  nobody;
worker_processes  1;
#error_log  logs/error.log;
#error_log  logs/error.log  notice; 
#error_log  logs/error.log  info;     
#pid        logs/nginx.pid;

events {
worker_connections  1024; }
rtmp {
#RTMP server
server {
listen 1935;
#server port
chunk_size 4096;
#chunk_size 
# vod server application vod { 
play /mnt/hgfs/dn_class/vod;
#media file position 
}
#live server 1 application live{ 
#Darren live first add live on;}
# live server 2 application live_cctv{ 
#Darren live  add live on; } } } ........  其他配置不需理會

在Ubuntu端用ffmpeg產生一個模擬直播源,向rtmp伺服器推送

推流

ffmpeg -re -i /mnt/hgfs/dn_class/vod/35.mp4 -c copy -f flv rtmp://192.168.100.33/live/35

注意,原始檔必須是H.264+AAC編碼的

拉流

ffplay rtmp://192.168.100.33/live/35

點播配置

1. 建立媒體資料夾/mnt/hgfs/dn_class/vod
把媒體檔案 35.mp4複製到/mnt/hgfs/dn_class/vod目錄下。
然後我們就可以開啟一個視訊點播的服務了。開啟配置檔案nginx.conf(路徑/usr/local/nginx/conf/nginx.conf),新增RTMP的配置。

 #user  nobody; 
 worker_processes  1;
 #error_log  logs/error.log;
 #error_log  logs/error.log  notice; #error_log  logs/error.log  info;     
 #pid        logs/nginx.pid;
 events {
 worker_connections  1024; }
 rtmp {
 #RTMP server
 server {
 listen 1935;
 #server port
 chunk_size 4096;
 #chunk_size application vod {
 play /mnt/hgfs/dn_class/vod;
 #media file position } } } ........  其他配置不需理會

聊天服務

特性

  • 輕量級
  • 高效能
  • 純Golang實現
  • 支援單個、多個、單房間以及廣播訊息推送
  • 支援單個Key多個訂閱者(可限制訂閱者最大人數)
  • 心跳支援(應用心跳和tcp、keepalive)
  • 支援安全驗證(未授權使用者不能訂閱)
  • 多協議支援(websocket,tcp)
  • 可拓撲的架構(job、logic模組可動態無限擴充套件)
  • 基於Kafka做非同步訊息推送

安裝

一、安裝依賴

$ yum -y install java-1.7.0-openjdk

二、安裝Kafka訊息佇列服務

kafka在官網已經描述的非常詳細,在這裡就不過多說明,安裝、啟動請檢視這裡.

三、搭建golang環境

1.下載原始碼(根據自己的系統下載對應的安裝包)

$ cd /data/programfiles
$ wget -c --no-check-certificate https://storage.googleapis.com/golang/go1.5.2.linux-amd64.tar.gz
$ tar -xvf go1.5.2.linux-amd64.tar.gz -C /usr/local

2.配置GO環境變數
(這裡我加在/etc/profile.d/golang.sh)

$ vi /etc/profile.d/golang.sh
# 將以下環境變數新增到profile最後面
export GOROOT=/usr/local/go
export PATH=$PATH:$GOROOT/bin
export GOPATH=/data/apps/go
$ source /etc/profile

四、部署im

1.下載goim及依賴包

$ yum install hg
$ go get -u github.com/Terry-Mao/goim
$ mv $GOPATH/src/github.com/Terry-Mao/goim $GOPATH/src/goim
$ cd $GOPATH/src/goim
$ go get ./...

2.安裝router、logic、comet、job模組(配置檔案請依據實際機器環境配置)

$ cd $GOPATH/src/goim/router
$ go install
$ cp router-example.conf $GOPATH/bin/router.conf
$ cp router-log.xml $GOPATH/bin/
$ cd ../logic/
$ go install
$ cp logic-example.conf $GOPATH/bin/logic.conf
$ cp logic-log.xml $GOPATH/bin/
$ cd ../comet/
$ go install
$ cp comet-example.conf $GOPATH/bin/comet.conf
$ cp comet-log.xml $GOPATH/bin/
$ cd ../logic/job/
$ go install
$ cp job-example.conf $GOPATH/bin/job.conf
$ cp job-log.xml $GOPATH/bin/

到此所有的環境都搭建完成!

五、啟動im

$ cd /$GOPATH/bin
$ nohup $GOPATH/bin/router -c $GOPATH/bin/router.conf 2>&1 > /data/logs/goim/panic-router.log &
$ nohup $GOPATH/bin/logic -c $GOPATH/bin/logic.conf 2>&1 > /data/logs/goim/panic-logic.log &
$ nohup $GOPATH/bin/comet -c $GOPATH/bin/comet.conf 2>&1 > /data/logs/goim/panic-comet.log &
$ nohup $GOPATH/bin/job -c $GOPATH/bin/job.conf 2>&1 > /data/logs/goim/panic-job.log &

如果啟動失敗,預設配置可通過檢視panic-xxx.log日誌檔案來排查各個模組問題.

六、測試

Arch

在這裡插入圖片描述

Benchmark Server

CPU Memory OS Instance
Intel(R) Xeon(R) CPU E5-2630 v2 @ 2.60GHz DDR3 32GB Debian GNU/Linux 8 1

Benchmark Case

  • Online: 1,000,000
  • Duration: 15min
  • Push Speed: 40/s (broadcast room)
  • Push Message: {“test”:1}
  • Received calc mode: 1s per times, total 30 times

Benchmark Resource

  • CPU: 2000%~2300%
  • Memory: 14GB
  • GC Pause: 504ms
  • Network: Incoming(450MBit/s), Outgoing(4.39GBit/s)

Benchmark Result

  • Received: 35,900,000/s

推送協議可檢視push http協議文件

配置

TODO

例子

Websocket: Websocket Client Demo

Android: Android

iOS: iOS

文件

push http協議文件推送介面

叢集

comet

comet 屬於接入層,非常容易擴充套件,直接開啟多個comet節點,修改配置檔案中的base節點下的server.id修改成不同值(注意一定要保證不同的comet程式值唯一),前端接入可以使用LVS 或者 DNS來轉發

logic

logic 屬於無狀態的邏輯層,可以隨意增加節點,使用nginx upstream來擴充套件http介面,內部rpc部分,可以使用LVS四層轉發

kafka

kafka 可以使用多broker,或者多partition來擴充套件佇列

router

router 屬於有狀態節點,logic可以使用一致性hash配置節點,增加多個router節點(目前還不支援動態擴容),提前預估好線上和壓力情況

job

job 根據kafka的partition來擴充套件多job工作方式,具體可以參考下kafka的partition負載


PHP 為什麼 “慢” ???

Laravel + Swoole 提速 30倍

  • 複用容器
  • 啟用協程
  • 資料庫連線池

  • 複用容器
    熟悉 Laravel 的朋友都知道 IoC 容器是整個框架的核心,幾乎所有 Laravel 提供的服務都被註冊在 IoC 容器中。每當容器啟動時,Laravel 就會將大部分服務註冊到容器中來,有些服務還會去載入檔案,比如配置、路由等,可以說啟動容器是比較 “耗時” 的。我們再次觀察上面的指令碼,可以看到 request 回撥的第一行就是建立 IoC 容器($app),這也意味著每次在處理請求時都會建立一次容器,這樣不僅重複執行了許多程式碼,還造成不小的 IO 開銷,所以上述指令碼顯然不是最優的做法。那我們試試只建立一個容器,再讓所有的請求都複用這個容器。我們可以在 worker 程式啟動時(也就是 workerStart 回撥中)建立並啟動容器,這樣在 request 回撥中就能複用了。現在將 swoole.php 如下:
<?php

require __DIR__.'/vendor/autoload.php';

use HuangYi\Shadowfax\Http\Request;
use HuangYi\Shadowfax\Http\Response;
use Illuminate\Contracts\Http\Kernel;
use Illuminate\Http\Request as IlluminateRequest;
use Swoole\Http\Server;

$server = new Server('127.0.0.1', 9501);

$server->set([
 'worker_num' => 1, 'enable_coroutine' => false,
]);

$app = null;

$server->on('workerStart', function () use (&$app) {
 $app = require __DIR__.'/bootstrap/app.php';

 $app->instance('request', IlluminateRequest::create('http://localhost'));
 $app->make(Kernel::class)->bootstrap();});

$server->on('request', function ($request, $response) use (&$app) {
 $kernel = $app->make(Kernel::class);
 $illuminateResponse = $kernel->handle( $illuminateRequest = Request::make($request)->toIlluminate()
 );
 Response::make($illuminateResponse)->send($response);

 $kernel->terminate($illuminateRequest, $illuminateResponse);});

$server->start();
  • 啟用協程
    協程是 Swoole 的最強武器,也是實現高併發的精髓所在。那麼在 Laravel 中使用協程會有問題嗎?首先啟動 Swoole 的協程特性,將 enable_coroutine 設定為 true 即可,然後在 routes/web.php 裡面新增兩個路由:
<?php

use Swoole\Coroutine;

app()->singleton('counter', function () {
 $counter = new stdClass; $counter->number = 0;
 return $counter;});

Route::get('one', function () {
 app('counter')->number = 1;
 Coroutine::sleep(5);
 echo sprintf("one: %d\n", app('counter')->number);
});

Route::get('two', function () {
 app('counter')->number = 2;
 Coroutine::sleep(5);
 echo sprintf("two: %d\n", app('counter')->number);
});

上述程式碼首先在容器裡面註冊了一個 counter 單例,路由 one 將 counter 單例的 number 屬性設定為 1,然後模擬協程被掛起 5 秒,恢復後列印出 number 屬性的值。路由 two 也類似,只是將 number 屬性設定為了 2。啟動伺服器後,我們先訪問 one,然後立馬訪問 two(間隔不要超過 5 秒)。我們可以觀察到 Console 輸出的資訊為:

one: 2
two: 2
  • 資料庫連線池
    注意: 在協程環境下使用資料庫如果不配合連線池,就會造成連線異常。當然,使用 Swoole 的 Channel 來建立連線池非常簡單,但是如果直接在業務程式碼中使用連線池,程式設計師需要自行控制何時取何時回收,而且還不能使用 Laravel 的 Model 了,這點我是絕對不能接受的。還有一點,由於在業務程式碼中使用了 Swoole 的介面,這意味著你的程式必須執行在 Swoole 之上,再也無法切回 PHP-FPM 了。Shadowfax 做到了無感知的使用連線池,開發者依然像平時那樣用 Model 來查詢或者更新資料,唯一需要做的就是將程式中使用到的資料庫連線名配置到 db_pools 當中即可。Shadowfax 是如何做到的呢?我們只需要搞清楚一點就能明白原理了,Laravel 中的資料庫連線都是通過 Illuminate\Database\DatabaseManager::connection() 方法來獲取的,我們可以繼承這個類並改造 connection() 方法,如果取的是 db_pools 中配置的連線,那麼就從對應的連線池中獲取。最後使用這個改造後的類注覆蓋原來的 db 服務即可。具體的實現就請閱讀原始碼 。
<?php

namespace HuangYi\Shadowfax\Laravel;

use Illuminate\Database\Connection;
use Illuminate\Database\Connectors\ConnectionFactory;
use Illuminate\Database\DatabaseManager as LaravelDatabaseManager;

class DatabaseManager extends LaravelDatabaseManager
{
 use HasConnectionPools;
 /** * The callback to be executed to reconnect to a database in pool. * * @var callable */ protected $poolReconnector;

 /** * Create a new DatabaseManager instance. * * @param  \Illuminate\Contracts\Foundation\Application $app
 * @param  \Illuminate\Database\Connectors\ConnectionFactory $factory
 * @param  array $poolsConfig
 * @return void */ public function __construct($app, ConnectionFactory $factory, array $poolsConfig = []) {  parent::__construct($app, $factory);

  $this->poolsConfig = $poolsConfig;

  $this->poolReconnector = function ($connection) {
  $this->poolReconnect($connection);
 }; }
 /** * Get a database connection instance. * * @param  string|null $name
 * @return \Illuminate\Database\ConnectionInterface */ public function connection($name = null)
 {  $name = $name ?: $this->getDefaultConnection();

 if (! $this->isPoolConnection($name)) {
 return parent::connection($name);
 }
 if ($connection = $this->getConnectionFromContext($name)) {
 return $connection; }
 return $this->getConnectionFromPool($name);
 }
 /** * Resolve the connection. * * @param  string $name
 * @return \Illuminate\Database\Connection */ protected function resolveConnection($name)
 { [$database, $type] = $this->parseConnectionName($name);

 $connection = $this->configure($this->makeConnection($database), $type);

 $connection->setReconnector($this->poolReconnector);

 return $connection; }
 /** * Get the connection key in coroutine context. * * @param  string $name
 * @return string */ protected function getConnectionKeyInContext($name)
 { return 'db.connections.'.$name;
 }
 /** * Reconnect to the given database. * * @param  string|null $name
 * @return \Illuminate\Database\Connection */ public function reconnect($name = null)
 {  $name = $name ?: $this->getDefaultConnection();

 if (! $this->isPoolConnection($name)) {
 return parent::reconnect($name);
 } }
 /** * Reconnect the connection in pool. * * @param  \Illuminate\Database\Connection $connection
 * @return \Illuminate\Database\Connection */ public function poolReconnect(Connection $connection)
 {  $connection->disconnect();

 $fresh = $this->makeConnection($connection->getName());

 return $connection
 ->setPdo($fresh->getRawPdo()) ->setReadPdo($fresh->getRawReadPdo()); }}

swoole擴充套件安裝

pecl install swoole

swoole框架

composer install

webroot目錄配置到Nginx/Apache的虛擬主機目錄中,使webroot/可訪問。

詳細部署說明

1. 安裝composer(php依賴包工具)

curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer

注意:如果未將php直譯器程式設定為環境變數PATH中,需要設定。因為composer檔案第一行為#!/usr/bin/env php,並不能修改。
更加詳細的對composer說明:blog.csdn.net/zzulp/article/details...

2. composer install

切換到PHPWeb專案目錄,執行指令composer install,如很慢則

composer install --prefer-dist

3. Ningx配置HTTPS

  • Apache請參照Nginx配置,自行修改實現
  • 這裡使用了www.xxx.com作為域名,需要配置host或者改成你的域名
server {
 listen       80; server_name  www.xxx.com; index index.html index.php;     location / {
 root   /path/to/web/webroot;
 proxy_set_header X-Real-IP $remote_addr; if (!-e $request_filename) { rewrite ^/(.*)$ /index.php; } }     location ~ .*\.(php|php5)?$ {
 fastcgi_pass  127.0.0.1:9000; fastcgi_index index.php; include fastcgi.conf; }}

**注意:https下必須採取wss So-有兩種方案 1.採用nginx 反向代理4431埠 swoole 的埠和4431進行通訊。2.swoole 確認是否啟用了openssl,是否在編譯時加入了--enable-openssl的支援,然後在set 證照路徑即可。兩種方案選擇其一就好,不過第一種方案有個潛在神坑就是你通過反向代理拿不到真實的IP地址了,這點值得注意,Nginx有辦法拿到真實的ip,不懂可以私聊我,光wss的坑太多了就不一一說了。**


何為 laravel-admin

是一個可以快速幫你構建後臺管理的工具,它提供的頁面元件和表單元素等功能,能幫助你使用很少的程式碼就實現功能完善的後臺管理功能

特性

  • 內建使用者和許可權系統
  • model-grid支援快速構建資料表格
  • model-form支援快速構建資料表單
  • model-tree支援快速構建樹狀資料
  • 內建40+種form元素元件、以及支援擴充套件元件
  • 支援Laravel的多種模型關係
  • mysql、mongodb、pgsql等多資料庫支援
  • 支援引入第三方前端庫
  • 資料庫和artisan命令列工具的web實現
  • 支援自定義圖表
  • 多種常用web元件
  • 支援本地和oss檔案上傳

目錄結構

app/Admin
├── Controllers
│   ├── ExampleController.php
│   └── HomeController.php
├── bootstrap.php
└── routes.php

克隆專案

git clone https://github.com/DOUBLE-Baller/momo.git

進入專案

cd momo

安裝功能包

composer install 

複製.env檔案

cp .env.example .env

生成金鑰

php artisan key:generate

執行遷移

# 注意修改.env檔案的資料庫資訊
php artisan migrate

建立檔案連結(如果報錯請百度解決,都是小問題)

php artisan storage:link

初始化資料庫

php artisan db:seed-sql 
# 輸入yes

後臺地址:xxxx/admin 賬戶:admin,密碼:admin

建立後臺控制器

# 以建立使用者管理為例
php artisan admin:controller UserController

注意:控制器裡面修改相應模型,變數,檢視即可,檢視請參考auth裡面的程式碼

使用說明

搜尋和匯出功能需自己完善

  • 路由檔案:app/Admin/routes.php
  • 配置檔案:config/admin.php
  • 語言檔案:resources/lang/zh-CN/admin.php
  • 後臺控制器路徑:app/Admin/Controllers
  • 後臺檢視路徑:app/Admin/Views
  • 檢視請參考auth裡面的程式碼
  • 檢視頁面程式碼請參考adminlte2.4檔案
  • 資原始檔:public/plugins
  • 獲取登入使用者Admin::user()
  • 獲取登入使用者IDAdmin::id()
  • 判斷登入使用者是否是某個角色(判斷角色標識)Admin::isAdmin('slug'['slug','slug'])
  • 檢視獲取登入使用者admin('user')
  • 檢視獲取登入使用者IDadmin('id')
  • 檢視判斷登入使用者是否是某個角色(判斷角色標識)admin('isAdmin','slug'['slug','slug'])

==問題反饋==

在使用中有任何問題,歡迎反饋給我們,可以用以下聯絡方式跟我們交流

整套直播教學視訊 進群后@群主索取
在這裡插入圖片描述

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章