Swoole
======
[![Build Status](https://api.travis-ci.org/swoole/swoole-src.svg)](https://travis-ci.org/swoole/swoole-src)
[![License](https://img.shields.io/badge/license-apache2-blue.svg)](LICENSE)
[![Join the chat at https://gitter.im/swoole/swoole-src](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/swoole/swoole-src?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Coverity Scan Build Status](https://scan.coverity.com/projects/11654/badge.svg)](https://scan.coverity.com/projects/swoole-swoole-src)
Swoole is an event-driven asynchronous & concurrent networking communication framework with high performance written only in C for PHP.
* __Document__: <https://www.swoole.co.uk/docs/>
* __API__: <https://rawgit.com/tchiotludo/swoole-ide-helper/english/docs/index.html>
* __IDE Helper__: <https://github.com/swoole/ide-helper>
* __中文文档__: <http://wiki.swoole.com/>
* __Twitter__: <https://twitter.com/php_swoole>
* __Slack Group__: <https://swoole.slack.com/>
Swoft Framework
----
Modern High performance AOP and Coroutine PHP Framework, base on Swoole 2 <https://github.com/swoft-cloud>
Event-based
------
The network layer in Swoole is event-based and takes full advantage of the underlaying epoll/kqueue implementation, making it really easy to serve thousands of connections.
Coroutine
----------------
[Swoole 2.0](Version2.md) supports the built-in coroutine, and you can use fully synchronized code to implement asynchronous programs. PHP code without any additional keywords, the underlying automatic coroutine-scheduling.
```php
<?php
for ($i = 0; $i < 100; $i++) {
Swoole\Coroutine::create(function() use ($i) {
$redis = new Swoole\Coroutine\Redis();
$res = $redis->connect('127.0.0.1', 6379);
$ret = $redis->incr('coroutine');
$redis->close();
if ($i == 50) {
Swoole\Coroutine::create(function() use ($i) {
$redis = new Swoole\Coroutine\Redis();
$res = $redis->connect('127.0.0.1', 6379);
$ret = $redis->set('coroutine_i', 50);
$redis->close();
});
}
});
}
```
```php
<?php
$server = new Swoole\Http\Server('127.0.0.1', 9501);
$server->on('Request', function($request, $response) {
$tcp_cli = new Swoole\Coroutine\Client(SWOOLE_SOCK_TCP);
$ret = $tcp_cli->connect('127.0.0.1', 9906);
$tcp_cli ->send('test for the coroutine');
$ret = $tcp_cli->recv(5);
$tcp_cli->close();
if ($ret) {
$response->end(' swoole response is ok');
}
else{
$response->end(" recv failed error : {$client->errCode}");
}
});
$server->start();
```
Short API Name
-----
#### start a new coroutine
```php
go(function () {
co::sleep(0.5);
echo "hello";
});
go("test");
go([$object, "method"]);
```
#### Channel
```php
$chan = new chan(128);
$chan->push(1234);
$chan->push(1234.56);
$chan->push("hello world");
$chan->push(["hello world"]);
$chan->push(new stdclass);
$chan->push(fopen("test.txt", "r+"));
while($chan->pop());
```
#### MySQL Client
```php
go(function () {
$db = new Co\MySQL();
$server = array(
'host' => '127.0.0.1',
'user' => 'root',
'password' => 'root',
'database' => 'test',
);
$db->connect($server);
$result = $db->query('SELECT * FROM userinfo WHERE id = 3');
var_dump($result);
});
```
#### Redis Client
```php
go(function () {
$redis = new Co\Redis;
$res = $redis->connect('127.0.0.1', 6379);
$ret = $redis->set('key', 'value');
var_dump($redis->get('key'));
});
```
#### Http Client
```php
go(function () {
$http = new Co\Http\Client("www.google.com", 443, true);
$http->setHeaders(function () {
});
$ret = $http->get('/');
var_dump($http->body);
});
```
#### Http2 Client
```php
go(function () {
$http = new Co\Http2\Client("www.google.com", 443, true);
$req = new co\Http2\Request;
$req->path = "/index.html";
$req->headers = [
'host' => "www.google.com",
"user-agent" => 'Chrome/49.0.2587.3',
'accept' => 'text/html,application/xhtml+xml,application/xml',
'accept-encoding' => 'gzip',
];
$req->cookies = ['name' => 'rango', 'email' => 'rango@swoole.com'];
$ret = $http->send($req);
var_dump($http->recv());
});
```
#### Other
```php
co::sleep(100);
co::fread($fp);
co::gethostbyname('www.google.com');
```
Concurrent
------
On the request processing part, Swoole uses a multi-process model. Every process works as a worker. All business logic is executed in workers, synchronously.
With the synchronous logic execution, you can easily write large and robust applications and take advantage of almost all libraries available to the PHP community.
In-memory
------
Unlike traditional apache/php-fpm stuff, the memory allocated in Swoole will not be freed after a request, which can improve performance a lot.
## Why Swoole?
Traditional PHP applications almost always run behind Apache/Nginx, without much control of the request. This brings several limitations:
1. All memory will be freed after the request. All PHP code needs be re-compiled on every request. Even with opcache enabled, all opcode still needs to be re-executed.
2. It is almost impossible to implement long connections and connection pooling techniques.
3. Implementing asynchronous tasks requires third-party queue servers, such as rabbitmq and beanstalkd.
4. Implementing realtime applications such as chatting servers requires third-party languages, such as nodejs, for example.
This is why Swoole appeared. Swoole extends the use cases of PHP, and brings all these possibilities to the PHP world.
By using Swoole, you can build enhanced web applications with more control, real-time chatting servers, etc, more easily.
## Requirements
* Version-1: PHP 5.3.10 or later
* Version-2: PHP 5.5.0 or later
* Linux, OS X and basic Windows support (thanks to cygwin)
* GCC 4.4 or later
## Installation
1. Install via pecl
```
pecl install swoole
```
2. Install from source
```
sudo apt-get install php5-dev
git clone https://github.com/swoole/swoole-src.git
cd swoole-src
phpize
./configure
make && make install
```
## Introduction
Swoole includes components for different purposes: Server, Task Worker, Timer, Event and Async IO. With these components, Swoole allows you to build many features.
### Server
This is the most important part in Swoole. It provides the necessary infrastructure to build server applications.
With Swoole server, you can build web servers, chat messaging servers, game servers and almost anything you want.
The following example shows a simple echo server.
```php
// Create a server instance
$serv = new swoole_server('127.0.0.1', 9501);
// Attach handler for connect event. Once the client has connected to the server, the registered handler will be
// executed.
$serv->on('connect', function ($serv, $fd) {
echo "Client:Connect.\n";
});
// Attach handler for receive event. Every piece of data will be received by server and the registered handler will be
// executed. All custom protocol implementation should be located there.
$serv->on('receive', function ($serv, $fd, $from_id, $data) {
$serv->send($fd, $data);
});
$serv->on('close', function ($serv, $fd) {
echo "Client: Close.\n";
});
// Start our server, listen on the port and be ready to accept connections.
$serv->start();
```
Try to extend your server and implement what you want!
### HTTP Server
```php
$http = new swoole_http_server('0.0.0.0', 9501);
$http->on('request', function ($request, $response) {
$response->header('Content-Type', 'text/html; charset=utf-8');
$response->end('<h1>Hello Swoole. #' . rand(1000, 9999) . '</h1>');
});
$http->start();
```
### WebSocket Server
```php
$ws = new swoole_websocket_server('0.0.0.0', 9502);
$ws->on('open', function ($ws, $request) {