@phper
2018-04-18T09:49:03.000000Z
字数 4749
阅读 6042
swoole
swoole 内置实现了一个简单的httpServer,类似与node的httpServer。但是官方说swoole_http_server对Http协议的支持并不完整,建议仅作为应用服务器。并且在前端增加Nginx作为代理。实际生产环境,也是这样做的,前面加一层Nginx。
server {root /data/wwwroot/;server_name local.swoole.com;location / {proxy_http_version 1.1;proxy_set_header Connection "keep-alive";proxy_set_header X-Real-IP $remote_addr;if (!-e $request_filename) {proxy_pass http://127.0.0.1:9501;}}}
在swoole中通过读取$request->header['x-real-ip']来获取客户端的真实IP
先来一个我们用到的一个swoole HttpServer的例子,便于后面理解里面的设置。
$serv = new \swoole\http\server("127.0.0.1", 9501);$serv->on('Request', function ($request, $response) {//获取全局数据$_GET = $request->get;$_POST = $request->post;$_COOKIE = $request->cookie;$_FILES = $request->files;$_SERVER = $request->server;$_HEADER = $request->header;$_CONTENT = $request->rawContent();//TODO逻辑//SomeThingif ($todoTrue) {$response->end('success');} else {$response->status(500);}});$serv->start();
上面的demo中已经简单了写了下如何从request中获取各种数据。下面简单说下。
http请求过来的头部信息。有些可能我们是有用的。
通过$request->header['XXX']获得。
打印全部header数据看看:
echo json_encode($request->header);{"host": "127.0.0.1:9501","connection": "keep-alive","pragma": "no-cache","cache-control": "no-cache","upgrade-insecure-requests": "1","user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36","accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8","accept-encoding": "gzip, deflate, sdch, br","accept-language": "zh-CN,zh;q=0.8,en;q=0.6,tr;q=0.4,zh-TW;q=0.2"}
等同于php的全局函数$_SERVER,用来获取服务端的信息。只不过key都是小写了。
通过$request->server['xxx']获得。
打印全部server数据看看:
echo json_encode($request->server);{"query_string": "a=11","request_method": "GET","request_uri": "/","path_info": "/","request_time": 1493204184,"request_time_float": 1493204199.6719,"server_port": 9501,"remote_port": 55411,"remote_addr": "127.0.0.1","server_protocol": "HTTP/1.1","server_software": "swoole-http-server"}
Http请求的GET参数,相当于PHP中的$_GET,格式为数组。
通过$request->get['xxx']获得。
http://127.0.0.1:9501/?a=11&c=22&f=33echo json_encode($request->get);{"a": "11","c": "22","f": "33"}
为防止HASH攻击,GET参数最大不允许超过128个
接受post数据,和php中$_POST一样,是一个数组
通过$request->post['xxx']获得。
我们用postman模拟post数据提交了q1~q11等信息,然后打印出来。
var_dump($request->post);array(19) {'q1' =>string(1) "1"'q2' =>string(1) "2"'q3' =>string(1) "3"'q4' =>string(1) "4"'q5' =>string(1) "5"'q6' =>string(1) "6"'q7' =>string(1) "7"'q8' =>string(1) "8"'q9' =>string(1) "9"'q10' =>string(2) "10"'q11' =>string(2) "11"'q12' =>string(2) "12"'q13' =>string(2) "13"'q14' =>string(2) "14"'q15' =>string(2) "15"'q16' =>string(2) "16"'q17' =>string(6) "123456"'qq' =>string(2) "11"'tel' =>string(2) "22"}
HTTP请求携带的COOKIE信息,与PHP的$_COOKIE相同,格式为数组。
通过$request->cookie['xxx']获得。
echo $request->cookie['username'];
获取文件上传信息。类型为以form名称为key的二维数组。与PHP的$_FILES相同。
通过$request->file['form_name']获得。
Array([name] => facepalm.jpg[type] => image/jpeg[tmp_name] => /tmp/swoole.upfile.n3FmFr[error] => 0[size] => 15476)- name 浏览器上传时传入的文件名称- type MIME类型- tmp_name 上传的临时文件,文件名以/tmp/swoole.upfile开头- size 文件尺寸
上传的临时文件在调用$response->end后会自动删除,在end之后操作上传文件会抛出文件不存在错误
也可以自己设置上传文件的临时目录。
$serv->set(array('upload_tmp_dir' => '/data/uploadfiles/',));
目录最大长度不得超过220字节
response是服务器返回给客户端的信息,可以设置cookie,header,响应头等一系列信息。
设置的方法为:
$response->header(string $key, string $value);
- header设置必须在end方法之前
- $key必须完全符合Http的约定,每个单词首字母大写,不得包含中文,下划线或者其他特殊字符
- $value必须填写
$response->header('Content-Type', 'image/jpeg');
具体更多的response的header设置见文章:https://kb.cnblogs.com/page/92320/
设置HTTP响应的cookie信息。此方法参数与PHP的setcookie完全一致。
设置的方法为:
$response->cookie(string $key, string $value = '', int $expire = 0 , string $path = '/', string $domain = '', bool $secure = false , bool $httponly = false);
cookie设置必须在end方法之前
设置http 状态code码,常见的有 200, 404, 500等。
$response->status(int $http_status_code);
$http_status_code必须为合法的HttpCode,如200, 502, 301, 404等,否则会报错
必须在$response->end之前执行status。
$response->status(500);$response->end();
$response->end(string $html);
- end操作后将向客户端浏览器发送HTML内容,并销毁response对象
- 如果开启了KeepAlive,连接将会保持,服务器会等待下一次请求
- 未开启KeepAlive,服务器将会切断连接
既然有https server ,其实swoole也提供了http的client客户端,而且是默认是异步调用。由于异步用回调使用起来很蛋疼,而且,我们一般用php自带的curl就ok,所以也用不多,这里简单的说下。
<?phpSwoole\Async::dnsLookup("www.qq.com", function ($domainName, $ip) {$cli = new swoole_http_client($ip, 80);$cli->setHeaders(['Host' => $domainName,"User-Agent" => 'Chrome/49.0.2587.3','Accept' => 'text/html,application/xhtml+xml,application/xml','Accept-Encoding' => 'gzip',]);//回调$cli->get('/robots.txt', function ($cli) {echo "Length: " . strlen($cli->body) . "\n";echo $cli->body;$cli->close();});});
调用方式为:
function swoole_http_client->__construct(string $ip, int port, bool $ssl = false);
$host 如果为域名底层需要进行一次DNS查询,这是阻塞IO,请使用Swoole\Async::dnsLookup实现异步非阻塞。
由于swoole 2.0 以后,支持协程了。所以。异步http client就不多说了。会在下面的篇章中将协程httpClient.