随着WEB2.0的流行,现在很多网站都流行使用“弹幕”这种形式来实现互动。

弹幕(barrage),中文流行词语,原意指用大量或少量火炮提供密集炮击。大量以字幕弹(dàn)出形式显示的评论同时在屏幕上飘过的现象也被称为弹幕。

作为PHPer的我们,看到现在各种网站都有酷炫的弹幕飞过,我们是不是也想给自己的网站加入弹幕功能呢?

首先弹幕的后端其实说白了和公共聊天室的后端原理十分相似,都是一个客户端发送消息给服务端,服务端再将收到的消息广播给其他的客户端。对于后端来说他们几乎没区别,区别就在于前端。

好在我们有一个前端弹幕插件,这个插件是一个jquery插件,github地址:https://github.com/chiruom/jquery.danmu.js,基本上会使用jquery语法,看看示例代码就可以傻瓜化使用。

前端已经有了解决方案,但是后端呢?前端如何与后端通讯?用传统的ajax轮询吗?不行,这样效率太低,想想各大火爆的直播平台都是同一时间几万人在线,几千人同时发弹幕,如果靠ajax轮询一个php接口的话服务器会吃不消的。且弹幕消息存储方案略显复杂,有人问为什么要存储呢?因为ajax使用的HTTP协议是无状态协议,A客户端和B客户端之间对于服务器来说没有任何标志,如果服务器要确保A客户端和B客户端分别在两次请求的时候服务器只返回这两个客户端没有获取过的弹幕消息,那么服务器端就必须使用一个缓存来标识某某客户端看过哪条弹幕消息。综上所述ajax可以实现小规模的弹幕通信方案,但是很麻烦。

好在最新的HTML5中加入了WebSocket协议,我们可以通过WebSocket这种基于HTTP协议之上的即时通信协议来替代ajax这种传统的我问你答的老旧通信模式。而我们是PHPer,对于我们这种只懂PHP的人该如何编写WebSocket服务端呢?好在我们又得知PHP有一个Swoole扩展,我们在PHP语言中使用它可以很方便的构建一个WebSocket服务端。

关于Swoole的介绍可以参照他的官网http://www.swoole.com/,下面引用官网对它的一段简短的介绍。

PHP的异步、并行、高性能网络通信引擎,使用纯C语言编写,提供了PHP语言的异步多线程服务器,异步TCP/UDP网络客户端,异步MySQL,异步Redis,数据库连接池,AsyncTask,消息队列,毫秒定时器,异步文件读写,异步DNS查询。

Swoole内置了Http/WebSocket服务器端/客户端、Http2.0服务器端。

Swoole可以广泛应用于互联网、移动通信、企业软件、云计算、网络游戏、物联网(IOT)、车联网、智能家居等领域。

使用PHP+Swoole作为网络通信框架,可以使企业IT研发团队的效率大大提升,更加专注于开发创新产品。

先别被Swoole这么多的功能吓到了。我们先关注这里面的重点

Swoole内置了Http/WebSocket服务器端/客户端

意味着我们可以通过它构建WebSocket的服务端。看到这里我们是不是就急急忙忙去拿官网的WebSocket服务端代码做测试呢?不,Swoole是一个PHP扩展,意味着我们还得去安装它。是不是直接去下载so文件然后在php.ini中加入extension=swoole.so就可以了呢?还不是,我们先去看看Swoole扩展的依赖,这也是我们使用任何语言的任何外部包,外部模块,外部扩展最先要了解的问题。

环境依赖

仅支持Linux,FreeBSD,MacOS,3类操作系统

Linux内核版本2.3.32以上

PHP5.3.10以上版本,包括PHP7

gcc4.4以上版本或者clang

cmake2.4+,编译为libswoole.so作为C/C++库时需要使用cmake

PHP版本依赖

swoole仅支持PHP5.3.10或更高版本,建议使用PHP5.4+

swoole不依赖php的stream、sockets、pcntl、posix、sysvmsg等扩展。PHP只需安装最基本的扩展即可

意味着我们Windows下是无法使用这个扩展了(其实可以借助cygwin在win下使用swoole,但是考虑到我们使用swoole扩展就是为了性能,也为了熟悉以后的生产环节部署做准备,强烈推荐在linux下开发),那么我们把开发环境转移到Linux下进行吧。

接着还要求Linux内核版本为2.3.32以上,PHP为5.3.10以上,那么我们就用最新的CentOS吧,这个版本的yum安装的php直接就是PHP7最新版,根本无需考虑其他问题,当然你喜欢图形界面,用Ubuntu也可以。其他的基本上最新的Linux发行版都是符合版本要求的。

接着我们便来安装这个扩展,推荐使用PECL来安装,只需要一条

pecl install swoole

安装完扩展之后在命令行下输入

php -m

检查,如果有swoole那么说明安装成功了。

接下来就正式开始我们的编码旅程了。

开始编码旅程之前我们先看看最基础的效果原型是什么样子

没错就是这个样子,两个浏览器之前完全独立使用Websocket连接服务端,因此对于服务端来说这两个浏览器就相当于两个完全处在不同机器上的客户端。

效果看完了就开始来讲代码吧。

我们先看看官网的WebSocket服务端示例代码。

$serv = new Swoole\Websocket\Server("127.0.0.1", 9502);

$serv->on('Open', function($server, $req) {

echo "connection open: ".$req->fd;

});

$serv->on('Message', function($server, $frame) {

echo "message: ".$frame->data;

$server->push($frame->fd, json_encode(["hello", "world"]));

});

$serv->on('Close', function($server, $fd) {

echo "connection close: ".$fd;

});

$serv->start();

我们看到这个代码的第一行先是new了一个WebSocket服务端对象,并且在构造方法中的第一个参数指定了服务端监听的IP,第二个参数指定了服务端监听的端口。然后使用on方法为每一个事件设置了回调函数,最后一行start方法正式开始运行服务端。

这种写法非常像Javascript里面的异步调用,这也是Swoole中的事件驱动异步非阻塞特性,正因为是这种特性,每一个独立的事件(请求)会在服务端接收到之后分别异步处理,他们之间无需互相等待,这也是Swoole性能高的原因所在。

我们来分别剖析一下每一个事件的含义。

$serv->on('Open', function($server, $req) {

echo "connection open: ".$req->fd;

});

顾名思义,Open表示打开一个新的链接,并且在事件触发之后echo出连接上服务端的客户端id,该客户端唯一id为回调函数第二个参数中的fd字段。这也是服务端区分客户端的唯一id。

$serv->on('Message', function($server, $frame) {

echo "message: ".$frame->data;

$server->push($frame->fd, json_encode(["hello", "world"]));

});

同样顾名思义,Message表示消息到达服务端的事件,并且在事件触发之后echo出发送给服务端的数据,该数据为回调函数第二个参数的data字段。另外我们还看到它调用了$server->push,这是回调函数的第一个参数中的push方法,它是一个服务端给客户的发送数据的方法,第一个参数为要发送的客户端id,第二个为要发送的数据,这里的含义是向发给服务端消息的那个客户端发送["hello",

"world"]这个数组(方括号写数组为PHP5.4的新特性,如果你是PHP5.3请使用传统的array工厂函数生成数组)经过json序列化之后的数据。

$serv->on('Close', function($server, $fd) {

echo "connection close: ".$fd;

});

最后一个事件Close更加容易理解,就是关闭事件,当然关闭的不是服务端,而是客户端,可以理解为客户端与服务端断开连接的事件。回调函数中的代码含义为echo出与服务端断开连接的那个客户端id。

基本的API都清楚了,下面就直接看代码吧,短短二十行而已。

$server = new swoole_websocket_server("0.0.0.0", 1997);

$server->on('open', function (swoole_websocket_server $server, $request) {

echo "server: handshake success with fd{$request->fd}\n";//$request->fd 是客户端id

});

$server->on('message', function (swoole_websocket_server $server, $frame) {

echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n";

//$frame->fd 是客户端id,$frame->data是客户端发送的数据

//服务端向客户端发送数据是用 $server->push( '客户端id' , '内容')

$data = $frame->data;

foreach($server->connections as $fd){

$server->push($fd , $data);//循环广播

}

});

$server->on('close', function ($ser, $fd) {

echo "client {$fd} closed\n";

});

$server->start();

这里最核心的广播代码其实还用到了一个之前没有提到过的成员,也就是swoole_websocket_server对象的connections成员,这个成员中保存了所有已连接上该WebSocket服务端的fd,也就是客户端id。因此我们只要在message事件中使用foreach遍历该成员,循环将所有服务端收到的弹幕消息都发送给其他已连接上该服务端的客户端即可。

后端讲完了再讲讲前端吧。

var ws = new WebSocket("ws://192.168.1.107:1997");

ws.onopen = function(){

console.log("握手成功");

ws.send('hello world!!!');

};

ws.onmessage = function(e){

console.log("message:" + e.data);

var time = jQuery('#danmu').data("nowtime") + 1;

var text_obj = '{ "text":"' + e.data + '" , "color":"green" ,"size":"1","position":"0","time":"' + time + '" ,"isnew":" "}'; //构造加上了innew属性的字符串danmu对象

console.log(text_obj);

var new_obj = eval_r('(' + text_obj + ')'); //转化为js对象

jQuery('#danmu').danmu("add_danmu", new_obj); //向插件中添加该danmu对象

};

ws.onerror = function(){

console.log("error");

};

核心代码都在这里,使用new

WebSocket("ws://192.168.1.107:1997")创建一个WebSocket客户端连接对象,通过该对象的各种事件进行对应的操作,和服务端是不是很像?更多代码解释可以参考源代码中的注释,这里不做更多介绍。

看到这里相信作为一名PHPer的你也可以开发出属于自己的弹幕系统了。这里展示的只是一个最基础最原始的弹幕平台。我们也了解到了使用PHP开发一个弹幕平台需要涉及到的技术有WebSocket,Swoole扩展,甚至碰到了很多初级开发者平时不怎么接触的工具,比如说PECL,比如说Linux。

其实PHP结合Swoole扩展还可以做很多事情,比如说对接各种家电,对接各种硬件接口实现在Web端实时控制家电,又比如说结合树莓派做智能小车,通过web端进行遥控等等,各种新奇的玩法等你发现。谁说PHP只能做Web开发?PHP拥有了Swoole扩展其实能做的事情还有很多,Swoole就像他的宣传标题一样:重新定义PHP。

php主动推送弹幕_【转载】如何使用PHP构建一个高性能的弹幕后端服务相关推荐

  1. php mysql弹幕_如何使用PHP构建一个高性能的弹幕后端服务

    如何使用PHP构建一个高性能的弹幕后端服务 随着WEB2.0的流行,现在很多网站都流行使用"弹幕"这种形式来实现互动. 弹幕(barrage),中文流行词语,原意指用大量或少量火炮 ...

  2. 公众号向特定用户主动推送消息_小程序商城,商家神器!微信导购助手内测,能主动联系公众号粉丝...

    小程序·做出来·会使用 做小程序的钱才不白花 我们可以多聊聊,如何运营你的小程序? - 正 文 - 微信导购助手内测 "我公众号有几万粉丝,除了推文,我可以主动给他们发消息吗?" ...

  3. 公众号向特定用户主动推送消息_公众号助手——消息不仅可以群发,还不限制次数!...

    在这个资讯发达的当下,营销号十分活跃,不管是微博.微信,还是其他平台上都存在着各种类型的以营销为目的的账号.营销号通过对各种热点.时事发表评论收获流量和热度,或者是在特定领域内发表原创内容吸引粉丝,在 ...

  4. 【SpringBoot】服务器端主动推送SSE技术讲解

    =====================16.高级篇幅之SpringBoot2.0服务器端主动推送SSE技术讲解 ============================ 1.服务端推送常用技术介绍 ...

  5. 百度主动推送不收录怎么办?

    网站不录入,确实让很多站长挂心.收录直接关系着排名,没有收录何来排名.但随着百度算法的不断更新,百度关于收录的原则也越来越高,那么文章不收录是什么原因导致?自从百度站长平台开放了百度链接自动推送接口以 ...

  6. php主动推送弹幕_源起网-织梦发布文档主动百度推送熊掌推送批量推送

    源起网-织梦发布文档主动百度推送熊掌推送批量推送 环境要求 PHP必须开启了curl扩展 百度主动推送(实时)可以缩短百度爬虫发现您站点新链接的时间,使新发布的页面可以在第一时间被百度收录 织梦程序我 ...

  7. php主动推送弹幕_百万在线的美拍直播弹幕系统的实时推送技术实践之路

    1.内容概述 1.jpg (30.13 KB, 下载次数: 321) 2 年前 上传 直播弹幕是直播系统的核心功能之一.如何迅速作出一个有很好扩展性的弹幕系统?如何应对业务迅速发展?相信很多工程师/架 ...

  8. 怎么使用php提交百度收录_百度站长工具链接提交主动推送(实时)PHP推送教程

    特别声明:本文为原创,可自由转载.引用,但需署名作者且注明文章出处,如有侵权请联系! 百度站长工具的链接提交方式之一,"主动推送(实时)"提交方式可以向百度搜索引擎实时推送网站的最 ...

  9. 浏览器安全检查己通过_百度主动推送三项合一功能

    百度主动推送三项合一功能 作者:68喜 功能模块:搜索关键词记录推送熊掌号当天推送+熊掌号历史推送+普通主动推送 */ //错误显示屏蔽 error_reporting(E_ERROR | E_WAR ...

最新文章

  1. Agent admitted failure to sign using the key
  2. hadoop集群崩溃恢复记录
  3. ldap seach java_从LDAP(Java)检索信息
  4. 机器学习与不确定性_机器学习求职中的不确定性
  5. JavaScript易错知识点整理
  6. (笔记)网络技术学习交流会
  7. CoreAnimation-Layer详解
  8. 【从零开始学架构-李运华】01|架构到底是指什么?
  9. 鸿蒙系统深度系统,国产操作系统欢迎你!华为鸿蒙系统与深度deepin操作系统正常亮相...
  10. elasticsearch 数据类型
  11. WPA3 vs WPA2
  12. iOS读取通讯录功能
  13. python——用Turtle画画写名字
  14. php 微信平台,【php】微信公众平台
  15. 电子墨水屏(电子纸)科普篇
  16. Python画各种爱心
  17. 华硕Android原始密码,华硕(ASUS)路由器默认密码是多少?
  18. Smart Socket隐私权政策
  19. 【SoapUI “failed to load url” when “Error loading WSDL”】
  20. java计算还有几天生日_计算你的下一个生日还有多少天,是星期几?

热门文章

  1. 文献管理与信息分析(课堂笔记前六章)
  2. 基于改进FCOS的钢带表面缺陷检测算法
  3. 【​观察】与版权方合作 ,走上“正轨“的迅雷以后可以说什么样的故事?
  4. linux 内核笔记之watchdog
  5. 华中数控系统CNC数据采集
  6. Type c口和Micro USB作为电源接口,原理图设计
  7. vue js 多个对象拼接(变量名key拼接 + 值value拼接)
  8. Linux实验整理——vi编辑器使用、文件显示和处理命令
  9. 用LaTeX写论文时如何加资助信息
  10. 赛迪智库丨在符合伦理规范下做好AI全球化治理