来源: Swoole:PHP 协程框架 – DianThink点想网络
Swoole 是一个 PHP 的 协程 高性能 网络通信引擎,使用 C/C++ 语言编写,提供了多种通信协议的网络服务器和客户端模块。可以方便快速的实现 TCP/UDP服务、高性能Web、WebSocket服务、物联网、实时通讯、游戏、微服务等,使 PHP 不再局限于传统的 Web 领域。
Swoole 使 PHP 开发人员可以编写高性能高并发的 TCP、UDP、Unix Socket、HTTP、 WebSocket 等服务,让 PHP 不再局限于 Web 领域。
Swoole4 协程的成熟将 PHP 带入了前所未有的时期, 为性能的提升提供了独一无二的可能性。
Swoole 可以广泛应用于互联网、移动通信、云计算、 网络游戏、物联网(IOT)、车联网、智能家居等领域。
使用 PHP + Swoole 可以使企业 IT 研发团队的效率大大提升,更加专注于开发创新产品。
HTTP Server
//高性能HTTP服务器 $http = new Swoole\Http\Server( "127.0.0.1" , 9501); $http ->on( "start" , function ( $server ) { }); $http ->on( "request" , function ( $request , $response ) { $response ->header( "Content-Type" , "text/plain" ); $response -> end ( "Hello World\n" ); }); $http ->start(); |
WebSocket Server
$server = new Swoole\Websocket\Server( "127.0.0.1" , 9502); $server ->on( 'open' , function ( $server , $req ) { echo "connection open: {$req->fd}\n" ; }); $server ->on( 'message' , function ( $server , $frame ) { echo "received message: {$frame->data}\n" ; $server ->push( $frame ->fd, json_encode([ "hello" , "world" ])); }); $server ->on( 'close' , function ( $server , $fd ) { echo "connection close: {$fd}\n" ; }); $server ->start(); |
TCP Server
$server = new Swoole\Server( "127.0.0.1" , 9503); $server ->on( 'connect' , function ( $server , $fd ){ echo "connection open: {$fd}\n" ; }); $server ->on( 'receive' , function ( $server , $fd , $reactor_id , $data ) { $server ->send( $fd , "Swoole: {$data}" ); $server ->close( $fd ); }); $server ->on( 'close' , function ( $server , $fd ) { echo "connection close: {$fd}\n" ; }); $server ->start(); |
UDP Server
$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(); |
Task
$server = new Swoole\Server( "127.0.0.1" , 9502); $server ->set( array ( 'task_worker_num' => 4)); $server ->on( 'receive' , function ( $server , $fd , $reactor_id , $data ) { $task_id = $server ->task( "Async" ); echo "Dispatch AsyncTask: [id=$task_id]\n" ; }); $server ->on( 'task' , function ( $server , $task_id , $reactor_id , $data ) { echo "New AsyncTask[id=$task_id]\n" ; $server ->finish( "$data -> OK" ); }); $server ->on( 'finish' , function ( $server , $task_id , $data ) { echo "AsyncTask[$task_id] finished: {$data}\n" ; }); $server ->start(); |
Coroutine
//睡眠 1 万次,读取,写入,检查和删除文件 1 万次,使用 PDO 和 MySQLi 与数据库通信 1 万次,创建 TCP 服务器和多个客户端相互通信 1 万次, //创建 UDP 服务器和多个客户端到相互通信 1 万次...... 一切都在一个进程一秒内完美完成! Swoole\Runtime::enableCoroutine(); //此行代码后,文件操作,sleep,Mysqli,PDO,streams等都变成异步IO,见文档'一键协程化'章节 $s = microtime(true); //Co/run()见文档'协程容器'章节 Co\run( function () { // i just want to sleep... for ( $c = 100; $c --;) { go( function () { for ( $n = 100; $n --;) { usleep(1000); } }); } // 10k file read and write for ( $c = 100; $c --;) { go( function () use ( $c ) { $tmp_filename = "/tmp/test-{$c}.php" ; for ( $n = 100; $n --;) { $self = file_get_contents ( __FILE__ ); file_put_contents ( $tmp_filename , $self ); assert( file_get_contents ( $tmp_filename ) === $self ); } unlink( $tmp_filename ); }); } // 10k pdo and mysqli read for ( $c = 50; $c --;) { go( function () { $pdo = new PDO( 'mysql:host=127.0.0.1;dbname=test;charset=utf8' , 'root' , 'root' ); $statement = $pdo ->prepare( 'SELECT * FROM `user`' ); for ( $n = 100; $n --;) { $statement ->execute(); assert( count ( $statement ->fetchAll()) > 0); } }); } for ( $c = 50; $c --;) { go( function () { $mysqli = new Mysqli( '127.0.0.1' , 'root' , 'root' , 'test' ); $statement = $mysqli ->prepare( 'SELECT `id` FROM `user`' ); for ( $n = 100; $n --;) { $statement ->bind_result( $id ); $statement ->execute(); $statement ->fetch(); assert( $id > 0); } }); } // php_stream tcp server & client with 12.8k requests in single process function tcp_pack(string $data ): string { return pack( 'n' , strlen ( $data )) . $data ; } function tcp_length(string $head ): int { return unpack( 'n' , $head )[1]; } go( function () { $ctx = stream_context_create([ 'socket' => [ 'so_reuseaddr' => true, 'backlog' => 128]]); $socket = stream_socket_server( $errno , $errstr , STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $ctx ); if (! $socket ) { echo "$errstr ($errno)\n" ; } else { $i = 0; while ( $conn = stream_socket_accept( $socket , 1)) { stream_set_timeout( $conn , 5); for ( $n = 100; $n --;) { $data = fread ( $conn , tcp_length( fread ( $conn , 2))); assert( $data === "Hello Swoole Server #{$n}!" ); fwrite( $conn , tcp_pack( "Hello Swoole Client #{$n}!" )); } if (++ $i === 128) { fclose( $socket ); break ; } } } }); for ( $c = 128; $c --;) { go( function () { if (! $fp ) { echo "$errstr ($errno)\n" ; } else { stream_set_timeout( $fp , 5); for ( $n = 100; $n --;) { fwrite( $fp , tcp_pack( "Hello Swoole Server #{$n}!" )); $data = fread ( $fp , tcp_length( fread ( $fp , 2))); assert( $data === "Hello Swoole Client #{$n}!" ); } fclose( $fp ); } }); } // udp server & client with 12.8k requests in single process go( function () { $socket = new Swoole\Coroutine\Socket(AF_INET, SOCK_DGRAM, 0); $socket ->bind( '127.0.0.1' , 9503); $client_map = []; for ( $c = 128; $c --;) { for ( $n = 0; $n < 100; $n ++) { $recv = $socket ->recvfrom( $peer ); $client_uid = "{$peer['address']}:{$peer['port']}" ; $id = $client_map [ $client_uid ] = ( $client_map [ $client_uid ] ?? -1) + 1; assert( $recv === "Client: Hello #{$id}!" ); $socket ->sendto( $peer [ 'address' ], $peer [ 'port' ], "Server: Hello #{$id}!" ); } } $socket ->close(); }); for ( $c = 128; $c --;) { go( function () { if (! $fp ) { echo "$errstr ($errno)\n" ; } else { for ( $n = 0; $n < 100; $n ++) { fwrite( $fp , "Client: Hello #{$n}!" ); $recv = fread ( $fp , 1024); list( $address , $port ) = explode ( ':' , (stream_socket_get_name( $fp , true))); assert( $address === '127.0.0.1' && (int) $port === 9503); assert( $recv === "Server: Hello #{$n}!" ); } fclose( $fp ); } }); } }); echo 'use ' . (microtime(true) - $s ) . ' s' ; |
Channel
Co\run( function (){ //使用Channel进行协程间通讯 $chan = new Swoole\Coroutine\Channel(1); Swoole\Coroutine::create( function () use ( $chan ) { for ( $i = 0; $i < 100000; $i ++) { co::sleep(1.0); $chan ->push([ 'rand' => rand(1000, 9999), 'index' => $i ]); echo "$i\n" ; } }); Swoole\Coroutine::create( function () use ( $chan ) { while (1) { $data = $chan ->pop(); var_dump( $data ); } }); }); |
开源、高性能、高生产力
如果您有基于Swoole的优秀项目并想展现在下处,欢迎扫描侧边二维码来联系我们
Swoole源码 Swoole Plus Swoole Tracker Swoole Compiler
客服系统
即信在线客服系统是一套使用 Laravel+Swoole 编写的在线客服系统,支持 PC Web 和移动端 H5 网页,支持完善的权限管理和后台报表,聊天功能十分强大,支持语音聊天,微信留言等,并可以无缝接入微信公众号, 网页端只需嵌入一段 js 即可快速接入开源客服系统,可以无限添加用户,不限制坐席数 ,授权后可私有化部署,无数据安全问题, 并提供客服系统源码
聊天系统(JIM)
JIM 是一套使用 Swoole 编写的轻量级 IM 系统,界面简洁清爽,支持换肤,让在线办公更便捷,用 JIM 手机电脑上的文件都能收发自如,轻松完成你的工作和娱乐,支持丰富的表情包,视频聊天,语音聊天,群聊,单聊,消息漫游,输入检测等等常用的 IM 功能,授权后可私有化部署并二次开发,无数据安全问题,并提供一年的技术支持
物联网(IOT)解决方案
MQTT 是一个客户端服务端架构的发布 / 订阅模式的消息传输协议。它的设计思想是轻巧、开放、简单、规范,易于实现。这些特点使得它对很多场景来说都是很好的选择,特别是对于受限的环境如机器与机器的通信(M2M)以及物联网环境(IoT)。可以使用 Swoole 作为 MQTT 服务端或客户端,实现一套完整物联网(IOT)解决方案
新冠疫情抓取
基于 Swoole + imi 框架的新型冠状病毒肺炎疫情实时动态爬虫抓取项目,采集数据来源为丁香园。演示地址:https://test.yurunsoft.com/ncov/
PHP微服务(Micro Service)
Hyperf 是基于 Swoole 4.4+ 实现的高性能、高灵活性的 PHP 协程框架,内置协程服务器及大量常用的组件,性能较传统基于 PHP-FPM 的框架有质的提升,提供超高性能的同时,也保持着极其灵活的可扩展性,标准组件均基于 PSR 标准 实现,基于强大的依赖注入设计,保证了绝大部分组件或类都是可替换与可复用的
斗地主
基于 Swoole + Hyperf 框架开发 demo 级的斗地主游戏,实现斗地主游戏服务端逻辑,并采用原生 js 和 WebSocket 实现简单的客户端打牌逻辑,可以做到简单的玩斗地主游戏
魔兽世界
魔兽模拟游戏服务器,项目采用 PHP 开发,TCP 长连接基于 Swoole,支持鉴权,角色的创建,地图的加载,NPC 和生物的构建及各种眼花缭乱的物品和技能等等
HyperfCMS
HyperfCMS 是基于 Swoole+Hyperf 框架前后端分离架构的一套开源且完美的建站系统,拥有简单大气设计、友好的交互体验、清晰明了的代码规范。组件化的封装应用,编写复杂的管理应用,效率是质的提升、时间成倍缩短,人员可以减半,事半功倍。可以提供定制化服务!
实时视频语音 (Webrtc)
基于 Swoole4 高性能协程的 demo 级实时视频和语音通话方案,采用 webrtc 协议,并已经做好 p2p 打洞,中继服务器,演示地址:https://webrtc.dingjw.com/room.php?cid=2
一个基于 MySQL 协议,Swoole 开发的 MySQL 数据库连接池,支持读写分离支持数据库连接池,能够有效解决 PHP 带来的数据库连接瓶颈,支持 SQL92 标准,采用协程调度,遵守 MySQL 原生协议,跨语言,跨平台的通用中间件代理,支持 MySQL 事务,完美兼容 MySQL5.5 – 8.0
分布式定时任务 (Swoole Crontab)
基于 Swoole 的定时器程序,支持秒级处理,完全兼容 crontab 语法,且支持秒的配置,可使用数组规定好精确操作时间,Web 界面管理,增删改查任务,完整的权限控制
ThinkCMF
ThinkCMF 是一款基于 ThinkPHP+Mysql 开发的 CMS,完美支持 Swoole,框架自身提供基础的管理功能,而开发者可以根据自身的需求以应用的形式进行扩展。每个应用都能独立的完成自己的任务,也可通过系统调用其他应用进行协同工作。在这种运行机制下,开发商场应用的用户无需关心开发 SNS 应用时如何工作的,但他们之间又可通过系统本身进行协调,大大的降低了开发成本和沟通成本
Markdown文档系统
软擎文档系统是基于 Swoole + Rangine 框架开发的开源版 MarkDown 文档管理系统,不同于 docsify.js 等前端文档系统,本文档系统是偏后端的文档系统,对于广大PHPer来说更加友好。支持多用户协同操作,管理员审核发布等功能。 让您的工作更高效,更智慧。
Ain’t Queue 异步队列
Ain’t Queue 借助 Swoole 提供的便捷多进程 API 和 CSP 编程能力实现了主进程+监控进程+多工作进程的进程模型,并且提供了各类事件自定义注册的能力(队列监控、快照记录、任务中间件等)。默认使用 Redis 驱动,全原子操作,可延时可重试,自带漂亮的仪表盘,稳定可靠,已经在公司生产环境使用。
PaySDK
PHP 集成支付 SDK ,集成了支付宝、微信支付的支付接口和其它相关接口的操作。支持 php-fpm 和 Swoole,所有框架通用。
ZooKeeper
基于 Swoole 协程的PHP ZooKeeper客户端
LaravelS
LaravelS 是 Swoole 和 Laravel/Lumen 之间开箱即用的适配器,内置 HTTP/WebSocket Server,支持 TCP/UDP Server、自定义进程、异步的事件监听、异步任务、毫秒级定时任务、平滑Reload等特性,让 Laravel 如虎添翼。
xlswriter
xlswriter是一个 PHP C 扩展,支持 Swoole 协程环境,可用于在 Excel 2007+ XLSX 文件中读取数据,插入多个工作表,写入文本、数字、公式、日期、图表、图片和超链接。
Swoole 特性
Swoole 使用 C/C++ 语言编写,提供了 PHP 语言的异步多线程服务器、异步 TCP/UDP 网络客户端、异步 MySQL、异步 Redis、数据库连接池、AsyncTask、消息队列、毫秒定时器、异步文件读写、异步DNS查询。 Swoole内置了Http/WebSocket服务器端/客户端、Http2.0服务器端。
除了异步 IO 的支持之外,Swoole 为 PHP 多进程的模式设计了多个并发数据结构和IPC通信机制,可以大大 简化多进程并发编程的工作。其中包括了并发原子计数器、并发 HashTable、Channel、Lock、进程间通信IPC 等丰富的功能特性。
Swoole4.0 支持了类似 Go 语言的协程,可以使用完全同步的代码实现异步程序。PHP 代码无需额外增加任何 关键词,底层自动进行协程调度,实现异步IO。