swoole使用 常用案例
swoole使用
服务器及客户端
4种服务器【tcp/udp/web/websocket】
TCP服务器
//创建Server对象,监听 127.0.0.1:9501端口
$serv = new swoole_server("127.0.0.1", 9501);
//监听连接进入事件
$serv->on('connect', function ($serv, $fd) {
echo "Client: Connect.\n";
});
//监听数据接收事件
$serv->on('receive', function ($serv, $fd, $from_id, $data) {
$serv->send($fd, "Server: ".$data);
});
//监听连接关闭事件
$serv->on('close', function ($serv, $fd) {
echo "Client: Close.\n";
});
//启动服务器
$serv->start();
UDP服务器
//创建Server对象,监听 127.0.0.1:9502端口,类型为SWOOLE_SOCK_UDP
$serv = new swoole_server("127.0.0.1", 9502, SWOOLE_PROCESS, SWOOLE_SOCK_UDP);
//监听数据接收事件
$serv->on('Packet', function ($serv, $data, $clientInfo) {
$serv->sendto($clientInfo['address'], $clientInfo['port'], "Server ".$data);
var_dump($clientInfo);
});
//启动服务器
$serv->start();
http服务器
$http = new swoole_http_server("0.0.0.0", 9501);
$http->on('request', function ($request, $response) {
var_dump($request->get, $request->post);
$response->header("Content-Type", "text/html; charset=utf-8");
$response->end("<h1>Hello Swoole. #".rand(1000, 9999)."</h1>");
});
$http->start();
websocket服务器
服务器端:
//创建websocket服务器对象,监听0.0.0.0:9502端口
$ws = new swoole_websocket_server(“0.0.0.0”, 9502);
//监听WebSocket连接打开事件
$ws->on('open', function ($ws, $request) {
var_dump($request->fd, $request->get, $request->server);
$ws->push($request->fd, "hello, welcome\n");
});
//监听WebSocket消息事件
$ws->on('message', function ($ws, $frame) {
echo "Message: {$frame->data}\n";
$ws->push($frame->fd, "server: {$frame->data}");
});
//监听WebSocket连接关闭事件
$ws->on('close', function ($ws, $fd) {
echo "client-{$fd} is closed\n";
});
$ws->start();
客户端JS:
var wsServer = 'ws://192.168.50.151:9502';
var websocket = new WebSocket(wsServer);
websocket.onopen = function (evt) {
console.log("Connected to WebSocket server.");
};
websocket.onclose = function (evt) {
console.log("Disconnected");
};
websocket.onmessage = function (evt) {
console.log('Retrieved data from server: ' + evt.data);
};
websocket.onerror = function (evt, e) {
console.log('Error occured: ' + evt.data);
};
辅助
定时器
//每隔2000ms触发一次
swoole_timer_tick(2000, function ($timer_id) {
echo "tick-2000ms\n";
});
//3000ms后执行此函数
swoole_timer_after(3000, function () {
echo "after 3000ms.\n";
});
异步tcp服务器处理任务
$serv = new swoole_server("127.0.0.1", 9501);
//设置异步任务的工作进程数量
$serv->set(array('task_worker_num' => 4));
$serv->on('receive', function($serv, $fd, $from_id, $data) {
//投递异步任务
$task_id = $serv->task($data);
echo "Dispath AsyncTask: id=$task_id\n";
});
//处理异步任务
$serv->on('task', function ($serv, $task_id, $from_id, $data) {
echo "New AsyncTask[id=$task_id]".PHP_EOL;
//返回任务执行的结果
$serv->finish("$data -> OK");
});
//处理异步任务的结果
$serv->on('finish', function ($serv, $task_id, $data) {
echo "AsyncTask[$task_id] Finish: $data".PHP_EOL;
});
$serv->start();
tcp同步客户端
$client = new swoole_client(SWOOLE_SOCK_TCP);
//连接到服务器
if (!$client->connect('127.0.0.1', 9501, 0.5))
{
die("connect failed.");
}
//向服务器发送数据
if (!$client->send("hello world"))
{
die("send failed.");
}
//从服务器接收数据
$data = $client->recv();
if (!$data)
{
die("recv failed.");
}
echo $data;
//关闭连接
$client->close();
tcp异步客户端
$client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC);
//注册连接成功回调
$client->on("connect", function($cli) {
$cli->send("hello world\n");
});
//注册数据接收回调
$client->on("receive", function($cli, $data){
echo "Received: ".$data."\n";
});
//注册连接失败回调
$client->on("error", function($cli){
echo "Connect failed\n";
});
//注册连接关闭回调
$client->on("close", function($cli){
echo "Connection close\n";
});
//发起连接
$client->connect('127.0.0.1', 9501, 0.5);
自定义通讯协议设计
进程/协程管理
进程
单独进程
$process = new swoole_process('callback_function', true);
$pid = $process->start();
function callback_function(swoole_process $worker){
$worker->exec('/usr/bin/php', array(__DIR__.'/write_file.php'));
}// 启用本地的命令,加上绝对路径
swoole_process::wait();
【子进程】管道缓冲区读写及事件监听?
$workers = [];
$worker_num = 3;//创建的进程数
for($i=0;$i<$worker_num; $i++){
$process = new swoole_process('process');// 创建子进程 启动函数为 process
$pid = $process->start();// 子进程启动
$workers[$pid] = $process;// 存入字符数组
}
foreach($workers as $process){
//子进程会包含此事件,加入到子进程中 异步IO
swoole_event_add($process->pipe, function ($pipe) use($process){
$data = $process->read();
echo "RECV: " . $data.PHP_EOL;// 接收数据
});//函数调用的神奇情况
}
function process(swoole_process $process){// 第一个处理
$process->write("processId:".$process->pid);// 子进程写入信息到管道。
echo "echo:".$process->pid."\t".$process->callback .PHP_EOL;// 打印提示信息结果 及制表符
}
// 两次等待子进程结束
for($i=0; $i<$worker_num; $i++){// 回收子进程 否则出现僵尸进程
$ret = swoole_process::wait();// 回收结束运行的子进程,如果子进程结束。类似于 join
$pid = $ret['pid'];
unset($workers[$pid]);
echo "子进程退出, PID=".$pid.PHP_EOL;
}
队列读写
// 进程通信
$workers = [];// 进程仓库
$worker_num = 2;// 最大进程数
// 循环创建子进程
for($i = 0; $i < $worker_num; $i++){
$process = new swoole_process('callback_function', false, false);
$process->useQueue();// 开启队列使用,类似于全局队列
$pid = $process->start();//开启进程
$workers[$pid] = $process;// 存入句柄仓库
}
// 子进程执行函数
function callback_function(swoole_process $worker){
sleep(2);//睡觉2秒
$recv = $worker->pop();// 获取队列数据
echo "从主进程获取数据: $recv\n";
$worker->exit(0);// 当前子进程结束
}
// 主进程内,新增队列数据
foreach($workers as $pid => $process){
$process->push("Hello 子进程[$pid]\n");
}
// 两次等待子进程结束
for($i = 0; $i < $worker_num; $i++){
// 回收子进程 否则出现僵尸进程
$ret = swoole_process::wait();// 回收结束运行的子进程,如果子进程结束。类似于 join
$pid = $ret['pid'];
unset($workers[$pid]);
echo "子进程退出, PID=".$pid.PHP_EOL;
}
循环触发进程
// 循环定时执行
// 定时器触发函数
swoole_process::signal(SIGALRM, function () {
static $i = 0;
echo "#{$i}\t alarm\n";
$i++;
if ($i > 20) {
swoole_process::alarm(-1);// 清除定时器
}
});
//100ms
swoole_process::alarm(100 * 1000);// 定时器,类似于定时触发,类似js 里面的setinterval()
协程
2.0开始执行,暂不深入了解
内存读写
内存锁—互斥锁
$lock = new swoole_lock(SWOOLE_MUTEX);
echo "[主进程]创建锁\n";
$lock->lock();
if (pcntl_fork() > 0){// 这个是主进程
sleep(1);
$lock->unlock();
}else{// 这个是子进程
echo "[子进程]等待锁\n";
$lock->lock();
echo "[子进程]获取锁\n";
$lock->unlock();
exit("[子进程]退出\n");
}
echo "[主进程]释放锁\n";
unset($lock);
sleep(1);
echo "[主进程]退出\n";
异步IO
DNS轮询
swoole_async_dns_lookup("www.baidu.com", function($host, $ip){
echo "{$host} : {$ip}\n";
});
异步读取
swoole_async_readfile(__DIR__."/server.php", function($filename, $content) {
echo "$filename: $content";
});
异步写入
$file_content = 'jingshan';
swoole_async_writefile('test.log', $file_content, function($filename) {
echo "wirte ok.\n";
}, $flags = 0);
异步事件
$fp = stream_socket_client("tcp://www.qq.com:80", $errno, $errstr, 30);
fwrite($fp,"GET / HTTP/1.1\r\nHost: www.qq.com\r\n\r\n");
swoole_event_add($fp, function($fp) {
$resp = fread($fp, 8192);
//socket处理完成后,从epoll事件中移除socket
//var_dump($resp);
swoole_event_del($fp);
fclose($fp);
});
echo "Finish\n"; //swoole_event_add不会阻塞进程,这行代码会顺序执行
异步mysql
// mysql异步客户端
$db = new swoole_mysql;
$server = array(
'host' => '192.168.50.145',
'user' => 'root',
'password' => 'flzx_3QC',
'database' => 'mysql',
'chatset' => 'utf8', //指定字符集
);
$db->connect($server, function ($db, $r) {
if ($r === false){
var_dump($db->connect_errno, $db->connect_error);
die;
}
$sql = 'show tables';
$db->query($sql, function(swoole_mysql $db, $r) {
global $s;
if ($r === false){
var_dump($db->error, $db->errno);
}
elseif ($r === true ){
var_dump($db->affected_rows, $db->insert_id);
}
var_dump($r);
$db->close();
});
});
swoole使用 常用案例的更多相关文章
- css书写规范 & 页面布局规范 &常用案例经验总结
CSS 属性书写顺序(重点) 建议遵循以下顺序: 布局定位属性:display / position / float / clear / visibility / overflow(建议 displa ...
- Flume-1.8.0_部署与常用案例
该文章是基于 Hadoop2.7.6_01_部署 进行的 Flume官方文档:FlumeUserGuide 常见问题:记flume部署过程中遇到的问题以及解决方法(持续更新) 1. 前言 在一个完整的 ...
- Dom操作的常用案例实现
本文介绍几个Dom操作的几个常用的案例.虽然现在各种web框架层出不穷,也很方便.但是了解最基本的实现方法对我们开发还是有很大的帮助的: 1.图片滚动案例 1.1 效果如下: 1.2 代码如下: ...
- jQuery常用案例总结
模态对话框 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...
- shell 常用案例
此博文有自己写的其它朋友分享的,其中对其它朋友写的有问题的地方我简单做了一些修改,能保证运行. 1.写一个脚本通过ping命令测试192.168.0151到192.168.0.254之间的所有主机是否 ...
- 18.swoole学习笔记--案例
<?php //创建webSocket服务器 $ws=); //open $ws->on('open',function($ws,$request){ echo "新用户 $re ...
- JProfiler使用说明及常用案例分析
1 配置远程连接 (1)启动JProfiler,选择Attach to a running JVM (2)选择Quick Attach,然后选择On another computer,然后选择Edit ...
- Swoole 协程与 Go 协程的区别
Swoole 协程与 Go 协程的区别 进程.线程.协程的概念 进程是什么? 进程就是应用程序的启动实例. 例如:打开一个软件,就是开启了一个进程. 进程拥有代码和打开的文件资源,数据资源,独立的内存 ...
- 《Linux企业应用案例精解(第2版)》新书发售啦
本书在出版当年就获得了不错的销量,同时被中国科学院国家科学图书馆.中国国家图书馆.首都图书馆.清华大学.北京大学等上百所国内综合性大学图书馆收录为馆藏图书,在IT业界赢得了良好的口碑.随后2012年年 ...
随机推荐
- 详解meta标签
Meta标签详解,在网上转的,希望对大家有用 引言 您的个人网站即使做得再精彩,在"浩瀚如海"的网络空间中,也如一叶扁舟不易为人发现,如何推广个人网站,人们首先想到的方法无外乎以下 ...
- spring mvc和web-flow的整合方案
发现了一份整合spring MVC 和webflow的很好的资料,日后翻译出来发布.先记着. http://docs.spring.io/spring-webflow/docs/2.3.x/refer ...
- Mac系统安装nginx+rtmp模块
1.安装命令 ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install) ...
- [译]Selenium Python文档:三、导航控制
你使用WebDriver要做的第一件事就是访问一个链接.一般通过调用get方法来实现: driver.get("http://www.baidu.com") 在将控制权返给你的脚本 ...
- 提交任务到Spark
1.场景 在搭建好Hadoop+Spark环境后,现准备在此环境上提交简单的任务到Spark进行计算并输出结果.搭建过程:http://www.cnblogs.com/zengxiaoliang/p/ ...
- Luogu3373【模板】线段树2
P3373[模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格式: 第一行 ...
- RabbitMQ入门教程
1.下载安装RabbitMQ windows下 先 下载Erlang 64位 其它去这里下载 http://www.erlang.org/downloads 然后 下载RabbitMQ 官网 htt ...
- 持续集成:TestNG组织如何测试用例
持续集成:TestNG组织如何测试用例 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请大家咨询qq:90 ...
- 【LeetCode题解】排序
1. 排序 排序(sort)是一种常见的算法,把数据根据特定的顺序进行排列.经典的排序算法如下: 冒泡排序(bubble sort) 插入排序(insertion sort) 选择排序(selecti ...
- python 线程与进程
线程和进程简介 应用程序和进程以及线程的关系? 一个应用程序里可以有多个进程,一个进程里可以有多个线程 最原始的计算机是如何运行的? CPU是什么?为什么要使用多个CPU? 为什么要使用多线程? 为什 ...