Swoole笔记(三)
WebSocket
使用Swoole可以很简单的搭建异步非阻塞多进程的WebSocket服务器。
WebSocket服务器
<?php
$server = new swoole_websocket_server("0.0.0.0", 9501);
$server->set(array(
'daemonize' => false,
'worker_num' => 2,
));
$server->on('Start', function (swoole_websocket_server $server) {
echo "Server Start... \n";
swoole_set_process_name("swoole_websocket_server");
});
$server->on('ManagerStart', function (swoole_websocket_server $server) {
echo "ManagerStart\n";
});
$server->on('WorkerStart', function (swoole_websocket_server $server, $worker_id) {
echo "WorkerStart \n";
if ($server->worker_id == 0){
swoole_timer_tick(10000,function($id) use ($server) {
echo "test timer\n";
});
}
});
$server->on('Open', function (swoole_websocket_server $server, $request) {
echo "server: handshake success with fd{$request->fd}\n";
});
$server->on('Message', function (swoole_websocket_server $server, $frame) {
echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n";
$server->push($frame->fd, "this is server");
});
$server->on('Close', function ($ser, $fd) {
echo "client {$fd} closed\n";
});
$server->start();
shell里直接运行php swoole_ws_server.php启动即可。如果设置了后台运行,可以使用下列命令强杀进程:
kill -9 $(ps aux|grep swoole|grep -v grep|awk '{print $2}')
或者重新启动worker进程:
kill -10 $(ps aux|grep swoole_websocket_server|grep -v grep|awk '{print $2}')
输出:
[2017-06-01 22:06:21 $2479.0] NOTICE Server is reloading now.
WorkerStart
WorkerStart
注意:
- onMessage回调函数为必选,当服务器收到来自客户端的数据帧时会回调此函数。
/**
* @param $server
* @param $frame 包含了客户端发来的数据帧信息;使用$frame->fd获取fd;$frame->data获取数据内容
*/
function onMessage(swoole_server $server, swoole_websocket_frame $frame)
- 使用
$server->push()向客户端发送消息。长度最大不得超过2M。发送成功返回true,发送失败返回false。
function swoole_websocket_server->push(int $fd, string $data, int $opcode = 1, bool $finish = true);
WebSocket客户端
最简单的是使用JS编写:
socket = new WebSocket('ws://192.168.1.107:9501/');
socket.onopen = function(evt) {
// 发送一个初始化消息
socket.send('I am the client and I\'m listening!');
};
// 监听消息
socket.onmessage = function(event) {
console.log('Client received a message', event);
};
// 监听Socket的关闭
socket.onclose = function(event) {
console.log('Client notified socket has closed',event);
};
socket.onerror = function(evt) {
console.log('Client onerror',event);
};
Swoole里没有直接提供swoole_websocket客户端(注:自1.8.6后可以直接使用swoole内置的swoole_http_client实现swoole_websocket客户端),不过通过引入WebSocketClient.php文件可以实现:
<?php
require_once __DIR__ . '/WebSocketClient.php';
$client = new WebSocketClient('192.168.1.107', 9501);
if (!$client->connect())
{
echo "connect failed \n";
return false;
}
$send_data = "I am client.\n";
if (!$client->send($send_data))
{
echo $send_data. " send failed \n";
return false;
}
echo "send succ \n";
return true;
上面代码实现的是一个同步的swoole_websocket客户端。发送完消息会自动关闭,可以用来与php-fpm应用协作:将耗时任务使用客户端发送到swoole_websocket_server。
如何创建一个聊天室
实际项目里,我们可以将用户uid和fd进行双向绑定(暂不考虑多台服务器分布式部署情况),例如使用Redis保存:在onMessage进行用户信息验证后:
$this->redis->set($fd, $uid);
$this->redis->set($uid, $fd);
后续需要指定给某人发消息,只需要根据uid/fd发送即可。在onClose事件里进行解绑操作。群发的话只需要遍历一遍$server->connections即可。
示例(该项目只实现群发):
moell-peng/webim: PHP + Swoole 实现的简单聊天室
https://github.com/moell-peng/webim
HttpServer
swoole内置Http服务器的支持。swoole版的http server相对于php-fpm,最大优势在于高性能:代码一次载入内存,后续无需再解释执行。缺点是调试没有nginx+php-fpm方便。
使用swoole,通过几行代码即可写出一个异步非阻塞多进程的Http服务器:
<?php
$serv = new swoole_http_server("0.0.0.0", 9502);
$serv->on('Start', function() {
echo 'Start';
});
$serv->on('Request', function($request, $response) {
var_dump($request->get);
var_dump($request->post);
var_dump($request->cookie);
var_dump($request->files);
var_dump($request->header);
var_dump($request->server);
$response->cookie("User", "Swoole");
$response->header("X-Server", "Swoole");
$response->end("<h1>Hello Swoole!</h1>");
});
$serv->start();
shell里使用php swoole_http_server.php运行server。浏览器打开http://192.168.1.107:9502/即可看到输出。
Swoole笔记(三)的更多相关文章
- Oracle学习笔记三 SQL命令
SQL简介 SQL 支持下列类别的命令: 1.数据定义语言(DDL) 2.数据操纵语言(DML) 3.事务控制语言(TCL) 4.数据控制语言(DCL)
- 《CMake实践》笔记三:构建静态库(.a) 与 动态库(.so) 及 如何使用外部共享库和头文件
<CMake实践>笔记一:PROJECT/MESSAGE/ADD_EXECUTABLE <CMake实践>笔记二:INSTALL/CMAKE_INSTALL_PREFIX &l ...
- Mastering Web Application Development with AngularJS 读书笔记(三)
第一章笔记 (三) 一.Factories factory 方法是创建对象的另一种方式,与service相比更灵活,因为可以注册可任何任意对象创造功能.例如: myMod.factory('notif ...
- Python 学习笔记三
笔记三:函数 笔记二已取消置顶链接地址:http://www.cnblogs.com/dzzy/p/5289186.html 函数的作用: 給代码段命名,就像变量給数字命名一样 可以接收参数,像arg ...
- 《MFC游戏开发》笔记三 游戏贴图与透明特效的实现
本系列文章由七十一雾央编写,转载请注明出处. 313239 作者:七十一雾央 新浪微博:http://weibo.com/1689160943/profile?rightmod=1&wvr=5 ...
- [Firefly引擎][学习笔记三][已完结]所需模块封装
原地址:http://www.9miao.com/question-15-54671.html 学习笔记一传送门学习笔记二传送门 学习笔记三导读: 笔记三主要就是各个模块的封装了,这里贴 ...
- JSP学习笔记(三):简单的Tomcat Web服务器
注意:每次对Tomcat配置文件进行修改后,必须重启Tomcat 在E盘的DATA文件夹中创建TomcatDemo文件夹,并将Tomcat安装路径下的webapps/ROOT中的WEB-INF文件夹复 ...
- 构建高性能WEB站点笔记三
构建高性能WEB站点笔记三 第10章 分布式缓存 10.1数据库的前端缓存区 文件系统内核缓冲区,位于物理内存的内核地址空间,除了使用O_DIRECT标记打开的文件以外,所有对磁盘文件的读写操作都要经 ...
- Git 笔记三 Git的初步使用
Git 笔记三 Git的初步使用 在上一篇中,学习了如何配置Git环境,这一篇,开始学习Git的初步使用.Git的初步使用还是很简单的.总体上知道git init, git clone, git ad ...
- java之jvm学习笔记三(Class文件检验器)
java之jvm学习笔记三(Class文件检验器) 前面的学习我们知道了class文件被类装载器所装载,但是在装载class文件之前或之后,class文件实际上还需要被校验,这就是今天的学习主题,cl ...
随机推荐
- Go语言及Web框架Beego环境
Go语言及Web框架Beego环境无脑搭建 [原]Go语言及Web框架Beego环境无脑搭建 本文涉及软件均以截至到2013年10月12日的最新版本为准 1. 相关软件准备: 1) go1.2rc1. ...
- FarPoint.Win.Spread 自定义表头
最近C/S项目中用到FarPoint.Win.Spread,想在表头加个全选的checkbox,实现效果如图: 列的设置大家都清楚,直接可视化视图中设置该列CellType为CheckBox类型即 ...
- 从花式swap引出的pointer aliasing问题
上次,一个同学问我,你知不知道可以不用引入中间变量就可以实现swap? 我说,我知道,可以用加减法或者异或实现,像是这样 void mySwap(int &x,int &y) { x= ...
- 学习MVC之租房网站(六)-用户登录和权限控制
在上一篇<学习MVC之租房网站(五)-权限.角色.用户管理>完成了权限.角色.用户的增删改查,现在将基于前面完成的内容,进行后台用户登录和权限控制功能的开发. 一.用户登录 用户登录涉及到 ...
- c# 基础算法(一) 九九乘法
闲来无事,偶见某贴子里面讨论面试题.突然对一题产生了兴趣,做一道99乘法打印(主要是我工作了2家单位,还没有一家单位在面试时给我出这一道题)于是试着自己写写看.大概逻辑如下 class program ...
- 跟Microsoft.AspNet.Identity学习哈希加盐法
什么是哈希加盐法? 废话少说:对于MD5这种加密算法,同样的密码每次加密后得到的密文是一样的,所以黑客可以利用已知的密码库(彩虹库)对目标数据库密文进行对比进行攻击. 怎样解决:哈希加盐法,以下是网上 ...
- python——面向对象相关
其他相关 一.isinstance(obj, cls) 检查是否obj是否是类 cls 的对象 1 2 3 4 5 6 class Foo(object): pass obj = Foo( ...
- 如何使用HTML5自定义数据属性
在本文中,我将向你介绍如何使用HTML5自定义数据属性.我还将向你介绍一些开发人员在工作中经常使用的优秀实例. 为什么需要自定义数据属性? 很多时候我们需要存储一些与不同DOM元素相关联的信息.这些信 ...
- spine动画融合与动画叠加
spine动画融合与动画叠加 一.动画融合setMix 1.概述:两个动作之间的平滑过渡 参数duration为需要多少时间从fromAnimation过渡到toAnimation,过渡时间为动画重叠 ...
- 配置RMAN备份环境
关于配置RMAN备份环境你可以给每个目标数据库设置一些固定的配置,这些配置控制着RMAN多个方面的行为.例如,你可配置备份的保存策略.默认的备份目录.默认的备份设备类型等.你可以用show命令来查看配 ...