swoole--HTTP/WEBSOCKET协程客户端

2021-05-23

支持 Http-Chunk、Keep-Alive 特性,支持 form-data 格式
HTTP协议版本为HTTP/1.1
支持升级为WebSocket客户端
gzip压缩格式支持需要依赖zlib库
客户端仅实现核心的功能,实际项目建议使用 Saber

http客户端

use Swoole\Coroutine\Http\Client;
use function Swoole\Coroutine\run;

run(function () {
    $client = new Client($host, $port, $ssl = false);

    // 设置客户端参数,与Swoole\Client->set接收的参数完全一致
	$client->set([
	    'timeout' => 3,                  //超时,启用HTTP请求超时检测。单位为秒,最小粒度支持毫秒。
	    'keep_alive' => false,           //启用或关闭HTTP长连接。
	    'websocket_mask' => true,        //客户端启用或关闭掩码。开启会导致性能损耗
	    'websocket_compression' => true, //为true时允许对帧进行zlib压缩,具体是否能够压缩取决于服务端是否能够处理压缩
	]);

	// 设置HTTP请求头
	$client->setHeaders([
	    'Host'       => 'localhost',
	    'User-Agent' => 'Chrome/49.0.2587.3',
	    'Accept'     => 'text/html,application/xhtml+xml,application/xml',
	    'Accept-Encoding' => 'gzip',
	]);

	// 设置Cookie,值将会被进行urlencode编码,设置COOKIE后在客户端对象存活期间会持续保存; 服务器端主动设置的COOKIE会合并到cookies数组中
	$client->setCookies([]);

	// 上传文件,上传的文件会自动拼接到post方法的参数上
	// 上传字段为$name,文件地址为$path,MIME为$mimeType,不设置将根据文件后缀自动判断,$filename为文件名,
	// $offset为文件偏移量,$length为发送数据大小,默认全部,使用$offset和$length可以从文件中间开始传输,支持断点续传
	// Content-Type将自动变更为form-data
	// 底层基于sendfile,可支持异步发送超大文件
	$client->addFile($path, $name, $mimeType = null, $filename = null, $offset = 0, $length = 0)

	// 上传文件,上传的文件会自动拼接到post方法的参数上
	// 使用字符串$data(大小不能超过buffer_output_size)构建文件内容,上传字段为$name,文件MIME为$mimeType,默认为application/octet-stream,$filename为文件名
	// 使用字符串构建上传文件内容
	$client->addData(string $data, string $name, string $mimeType = null, string $filename = null);


	// 对地址$path发起GET请求,不能包括域名
	$client->get($path);

	// 对地址$path发起POST请求,参数为$data,不能包括域名,$data为数组是Content-Type自动设置为application/x-www-form-urlencoded
	$client->post($path, $data);

	// 下载HTTP远程文件文件$path,文件写入到本地$filename。写入偏移量为$offset(配合HTTP头Range:bytes=$offset可以实现断点续传)
	// 到数据后会写入到磁盘,而不是在内存中对HTTP Body进行拼接。因此download仅使用小量内存,就可以完成超大文件的下载。
	$client->download($path, $filename, $offset = 0);

	/**** 更底层的请求方法 *****/
	//设置请求方法。仅在当前请求有效,发送请求后会立刻清除method设置。
	$client->setMethod($method);

	// 设置HTTP请求的包体
	// 如果$data为数组时且Content-Type为urlencoded格式,底层将会自动进行 http_build_query,
	// 使用addFile或addData,字符串$data将会被忽略, 但$data为数组时底层将会以form-data格式追加数组中的字段
	// 未设置$method时底层会自动设置为POST
	$client->setData(string|array $data);

	// 更底层的HTTP请求方法请求$path,需要代码中调用setMethod和setData等接口设置请求的方法和数据。
	$client->execute($path);

	// 获取http响应的cookie数组
	$client->getCookies();

	// 获取http响应的头信息数组
	$client->getHeaders();

	// 获取http响应的状态码
	$client->getStatusCode();

	// 获取http响应的内容
	$client->getBody();


	// 关闭连接,close后如果再次请求get、post等方法时,Swoole会帮你重新连接服务器。
	$client->close();

	// 错误状态码,errCode的值等于Linux errno,可使用socket_strerror将错误码转为错误信息
	$client->errCode;
	//存储上次请求的返回包体。
	$client->body;
	//HTTP 状态码,如200、404等。状态码如果为负数,表示连接存在问题。
	$client->statusCode;
});

websocket客户端

use Swoole\Coroutine\Http\Client;
use function Swoole\Coroutine\run;

run(function () {
    $client = new Client($host, $port, $ssl = false);

    // 设置客户端参数,与Swoole\Client->set接收的参数完全一致
	$client->set([
	    'timeout' => 3,                  //超时,启用HTTP请求超时检测。单位为秒,最小粒度支持毫秒。
	    'keep_alive' => false,           //启用或关闭HTTP长连接。
	    'websocket_mask' => true,        //客户端启用或关闭掩码。开启会导致性能损耗
	    'websocket_compression' => true, //为true时允许对帧进行zlib压缩,具体是否能够压缩取决于服务端是否能够处理压缩
	]);

	// 将连接$path升级为WebSocket连接;upgrade会产生一次协程调度
	$client->upgrade($path);
	if ($client->statusCode == 200 || $client->statusCode == 403) {
		echo '服务器拒绝了握手请求';
	} else {
		// 向WebSocket服务器发送消息$data,$data为文本时$opcode设置为WEBSOCKET_OPCODE_TEXT(默认),$data为为二进制时$opcode设置为WEBSOCKET_OPCODE_BINARY
		// $finish表示是否压缩
		$client->push($data, $opcode = WEBSOCKET_OPCODE_TEXT, $finish = true);

		// 接收消息;执行成功返回frame对象
		$client->recv($timeout = 0);
	}

	// 关闭连接
	$client->close();
});

 

{/if}