今天这篇主要给大家介绍swoole与websocket实现即时通讯,实现视频弹幕效果
实现弹幕其实就和通讯,群聊类似,将消息推送给所有的客户端,不过前端的展示所有不同。
本地环境
后端 PHP 7.2.6、Swoole 4.3.1。
前端 HTML5 WebSocket、Canvas。
效果如图
终端效果批量版:
手动版:
下面我们来看看代码是如何实现的。
后端处理文件:server.php
<?phpclass Server{ private $serv; public function __construct() { $this->serv = new swoole_websocket_server("0.0.0.0", 9501); $this->serv->set([ 'worker_num' => 2, //开启2个worker进程 'max_request' => 4, //每个worker进程 max_request设置为4次 'task_worker_num' => 4, //开启4个task进程 'dispatch_mode' => 4, //数据包分发策略 - IP分配 'daemonize' => false, //守护进程(true/false) ]); $this->serv->on('Start', [$this, 'onStart']); $this->serv->on('Open', [$this, 'onOpen']); $this->serv->on("Message", [$this, 'onMessage']); $this->serv->on("Close", [$this, 'onClose']); $this->serv->on("Task", [$this, 'onTask']); $this->serv->on("Finish", [$this, 'onFinish']); $this->serv->start(); } public function onStart($serv) { echo "#### onStart ####".PHP_EOL; echo "SWOOLE ".SWOOLE_VERSION . " 服务已启动".PHP_EOL; echo "master_pid: {$serv->master_pid}".PHP_EOL; echo "manager_pid: {$serv->manager_pid}".PHP_EOL; echo "########".PHP_EOL.PHP_EOL; } public function onOpen($serv, $request) { echo "#### onOpen ####".PHP_EOL; echo "server: handshake success with fd{$request->fd}".PHP_EOL; $serv->task([ 'type' => 'login' ]); echo "########".PHP_EOL.PHP_EOL; } public function onTask($serv, $task_id, $from_id, $data) { echo "#### onTask ####".PHP_EOL; echo "#{$serv->worker_id} onTask: [PID={$serv->worker_pid}]: task_id={$task_id}".PHP_EOL; $msg = ''; switch ($data['type']) { case 'login': $msg = '我来了...'; break; case 'speak': $msg = $data['msg']; break; } foreach ($serv->connections as $fd) { $connectionInfo = $serv->connection_info($fd); if ($connectionInfo['websocket_status'] == 3) { $serv->push($fd, $msg); //长度最大不得超过2M } } $serv->finish($data); echo "########".PHP_EOL.PHP_EOL; } public function onMessage($serv, $frame) { echo "#### onMessage ####".PHP_EOL; echo "receive from fd{$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}".PHP_EOL; $serv->task(['type' => 'speak', 'msg' => $frame->data]); echo "########".PHP_EOL.PHP_EOL; } public function onFinish($serv,$task_id, $data) { echo "#### onFinish ####".PHP_EOL; echo "Task {$task_id} 已完成".PHP_EOL; echo "########".PHP_EOL.PHP_EOL; } public function onClose($serv, $fd) { echo "#### onClose ####".PHP_EOL; echo "client {$fd} closed".PHP_EOL; echo "########".PHP_EOL.PHP_EOL; }}$server = new Server();
前端:index.html
视频弹幕Demo
实现过程需要注意的几个地方
一、官网没有提供群聊的方法,所以群聊的处理方法我们用循环就好了。
单聊:
$serv->push($fd, $msg);
群聊:
foreach ($serv->connections as $fd) { $serv->push($fd, $msg);}
二、如何模拟批量弹幕效果?
可以使用 swoole_timer_tick ,比如:
swoole_timer_tick(50, function () use($serv){ $serv->task([ 'type' => 'login' ]);});
三、前端使用的弹幕插件:canvasBarrage.js
本教程实现的弹幕插件地址:http://www.zhangxinxu.com/wordpress/?p=6386
其他的比如有:Jquery.barrager.js,Jquery.danmu.js,DanMuer.js ,更多实现方法可以自己去研究与尝试!