[关闭]
@phper 2018-04-18T17:49:03.000000Z 字数 4749 阅读 5492

swoole深入学习 6. HttpServer和HttpClient

swoole


swoole 内置实现了一个简单的httpServer,类似与node的httpServer。但是官方说swoole_http_server对Http协议的支持并不完整,建议仅作为应用服务器。并且在前端增加Nginx作为代理。实际生产环境,也是这样做的,前面加一层Nginx。

nginx+swoole配置

  1. server {
  2. root /data/wwwroot/;
  3. server_name local.swoole.com;
  4. location / {
  5. proxy_http_version 1.1;
  6. proxy_set_header Connection "keep-alive";
  7. proxy_set_header X-Real-IP $remote_addr;
  8. if (!-e $request_filename) {
  9. proxy_pass http://127.0.0.1:9501;
  10. }
  11. }
  12. }

在swoole中通过读取$request->header['x-real-ip']来获取客户端的真实IP

一个完整的swoole httpServer例子

先来一个我们用到的一个swoole HttpServer的例子,便于后面理解里面的设置。

  1. $serv = new \swoole\http\server("127.0.0.1", 9501);
  2. $serv->on('Request', function ($request, $response) {
  3. //获取全局数据
  4. $_GET = $request->get;
  5. $_POST = $request->post;
  6. $_COOKIE = $request->cookie;
  7. $_FILES = $request->files;
  8. $_SERVER = $request->server;
  9. $_HEADER = $request->header;
  10. $_CONTENT = $request->rawContent();
  11. //TODO逻辑
  12. //SomeThing
  13. if ($todoTrue) {
  14. $response->end('success');
  15. } else {
  16. $response->status(500);
  17. }
  18. });
  19. $serv->start();

swoole_http_request获取request数据

上面的demo中已经简单了写了下如何从request中获取各种数据。下面简单说下。

header 信息

http请求过来的头部信息。有些可能我们是有用的。

通过$request->header['XXX']获得。

打印全部header数据看看:

  1. echo json_encode($request->header);
  2. {
  3. "host": "127.0.0.1:9501",
  4. "connection": "keep-alive",
  5. "pragma": "no-cache",
  6. "cache-control": "no-cache",
  7. "upgrade-insecure-requests": "1",
  8. "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",
  9. "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
  10. "accept-encoding": "gzip, deflate, sdch, br",
  11. "accept-language": "zh-CN,zh;q=0.8,en;q=0.6,tr;q=0.4,zh-TW;q=0.2"
  12. }

server 信息

等同于php的全局函数$_SERVER,用来获取服务端的信息。只不过key都是小写了。

通过$request->server['xxx']获得。

打印全部server数据看看:

  1. echo json_encode($request->server);
  2. {
  3. "query_string": "a=11",
  4. "request_method": "GET",
  5. "request_uri": "/",
  6. "path_info": "/",
  7. "request_time": 1493204184,
  8. "request_time_float": 1493204199.6719,
  9. "server_port": 9501,
  10. "remote_port": 55411,
  11. "remote_addr": "127.0.0.1",
  12. "server_protocol": "HTTP/1.1",
  13. "server_software": "swoole-http-server"
  14. }

get 信息

Http请求的GET参数,相当于PHP中的$_GET,格式为数组。

通过$request->get['xxx']获得。

  1. http://127.0.0.1:9501/?a=11&c=22&f=33
  2. echo json_encode($request->get);
  3. {
  4. "a": "11",
  5. "c": "22",
  6. "f": "33"
  7. }

为防止HASH攻击,GET参数最大不允许超过128个

post

接受post数据,和php中$_POST一样,是一个数组

通过$request->post['xxx']获得。

我们用postman模拟post数据提交了q1~q11等信息,然后打印出来。

  1. var_dump($request->post);
  2. array(19) {
  3. 'q1' =>
  4. string(1) "1"
  5. 'q2' =>
  6. string(1) "2"
  7. 'q3' =>
  8. string(1) "3"
  9. 'q4' =>
  10. string(1) "4"
  11. 'q5' =>
  12. string(1) "5"
  13. 'q6' =>
  14. string(1) "6"
  15. 'q7' =>
  16. string(1) "7"
  17. 'q8' =>
  18. string(1) "8"
  19. 'q9' =>
  20. string(1) "9"
  21. 'q10' =>
  22. string(2) "10"
  23. 'q11' =>
  24. string(2) "11"
  25. 'q12' =>
  26. string(2) "12"
  27. 'q13' =>
  28. string(2) "13"
  29. 'q14' =>
  30. string(2) "14"
  31. 'q15' =>
  32. string(2) "15"
  33. 'q16' =>
  34. string(2) "16"
  35. 'q17' =>
  36. string(6) "123456"
  37. 'qq' =>
  38. string(2) "11"
  39. 'tel' =>
  40. string(2) "22"
  41. }

HTTP请求携带的COOKIE信息,与PHP的$_COOKIE相同,格式为数组。

通过$request->cookie['xxx']获得。

  1. echo $request->cookie['username'];

file

获取文件上传信息。类型为以form名称为key的二维数组。与PHP的$_FILES相同。

通过$request->file['form_name']获得。

  1. Array
  2. (
  3. [name] => facepalm.jpg
  4. [type] => image/jpeg
  5. [tmp_name] => /tmp/swoole.upfile.n3FmFr
  6. [error] => 0
  7. [size] => 15476
  8. )
  9. - name 浏览器上传时传入的文件名称
  10. - type MIME类型
  11. - tmp_name 上传的临时文件,文件名以/tmp/swoole.upfile开头
  12. - size 文件尺寸

上传的临时文件在调用$response->end后会自动删除,在end之后操作上传文件会抛出文件不存在错误

也可以自己设置上传文件的临时目录。

  1. $serv->set(array(
  2. 'upload_tmp_dir' => '/data/uploadfiles/',
  3. ));

目录最大长度不得超过220字节

swoole_http_response 设置response信息

response是服务器返回给客户端的信息,可以设置cookie,header,响应头等一系列信息。

header 设置响应头

设置的方法为:

$response->header(string $key, string $value);
  • header设置必须在end方法之前
  • $key必须完全符合Http的约定,每个单词首字母大写,不得包含中文,下划线或者其他特殊字符
  • $value必须填写
  1. $response->header('Content-Type', 'image/jpeg');

具体更多的response的header设置见文章:https://kb.cnblogs.com/page/92320/

设置HTTP响应的cookie信息。此方法参数与PHP的setcookie完全一致。

设置的方法为:

  1. $response->cookie(string $key, string $value = '', int $expire = 0 , string $path = '/', string $domain = '', bool $secure = false , bool $httponly = false);

cookie设置必须在end方法之前

status 设置状态code码

设置http 状态code码,常见的有 200, 404, 500等。

$response->status(int $http_status_code);

$http_status_code必须为合法的HttpCode,如200, 502, 301, 404等,否则会报错
必须在$response->end之前执行status。

  1. $response->status(500);
  2. $response->end();

end 发送Http响应体,并结束请求处理

$response->end(string $html);
  • end操作后将向客户端浏览器发送HTML内容,并销毁response对象
  • 如果开启了KeepAlive,连接将会保持,服务器会等待下一次请求
  • 未开启KeepAlive,服务器将会切断连接

swoole http client

既然有https server ,其实swoole也提供了http的client客户端,而且是默认是异步调用。由于异步用回调使用起来很蛋疼,而且,我们一般用php自带的curl就ok,所以也用不多,这里简单的说下。

  1. <?php
  2. Swoole\Async::dnsLookup("www.qq.com", function ($domainName, $ip) {
  3. $cli = new swoole_http_client($ip, 80);
  4. $cli->setHeaders([
  5. 'Host' => $domainName,
  6. "User-Agent" => 'Chrome/49.0.2587.3',
  7. 'Accept' => 'text/html,application/xhtml+xml,application/xml',
  8. 'Accept-Encoding' => 'gzip',
  9. ]);
  10. //回调
  11. $cli->get('/robots.txt', function ($cli) {
  12. echo "Length: " . strlen($cli->body) . "\n";
  13. echo $cli->body;
  14. $cli->close();
  15. });
  16. });

调用方式为:

function swoole_http_client->__construct(string $ip, int port, bool $ssl = false);

$host 如果为域名底层需要进行一次DNS查询,这是阻塞IO,请使用Swoole\Async::dnsLookup实现异步非阻塞。

由于swoole 2.0 以后,支持协程了。所以。异步http client就不多说了。会在下面的篇章中将协程httpClient.

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注