wpjscc/reactphp-eventsource
Composer 安装命令:
composer require wpjscc/reactphp-eventsource
包简介
Instant real-time updates. Lightweight EventSource client receiving live messages via HTML5 Server-Sent Events (SSE). Fast stream processing built on top of ReactPHP's event-driven architecture.
README 文档
README
composer require wpjscc/reactphp-eventsource -vvv dev-master
try {
$result = React\Async\await(translate('Meet Winter CMS'));
// promise successfully fulfilled with $result
echo 'Result: ' . $result;
} catch (Throwable $e) {
// promise rejected with $e
echo 'Error: ' . $e->getMessage();
}
function translate($text) {
$deferred = new React\Promise\Deferred();
$es = new \Clue\React\EventSource\EventSource([
"POST",
'https://api.openai.com/v1/completions',
[
'Authorization' => 'Bearer sk-bdRUebZTlQpQndm1hhmRT3BlbkFJOqRLYJoV4u4eWY3APC',
'Content-Type' => 'application/json',
],
json_encode([
'model' => 'text-davinci-003',
// 'model' => 'text-davinci-002-render',
'prompt' => "Translate into Chinese and keep the source code
```md
$text
```",
'temperature' => 0,
"max_tokens" => 1500,
"frequency_penalty" => 0,
"presence_penalty" => 0.6,
"stream" => true,
])
]);
$es->on('open', function () {
echo 'open';
});
$replay = '';
$es->on('message', function (\Clue\React\EventSource\MessageEvent $message) use (&$replay) {
$json = json_decode($message->data, true);
if ($json) {
$replay .= $json['choices'][0]['text'];
echo $json['choices'][0]['text']."\n";
} else {
echo $message->data;
}
});
$es->on('error', function ($e) use ($es, $deferred, &$replay) {
$es->readyState = \Clue\React\EventSource\EventSource::CLOSED;
$deferred->resolve($replay);
echo $e->getMessage();
});
return $deferred->promise();
}
clue/reactphp-eventsource
Instant real-time updates. Lightweight EventSource client receiving live messages via HTML5 Server-Sent Events (SSE). Fast stream processing built on top of ReactPHP's event-driven architecture.
Table of contents
Support us
We invest a lot of time developing, maintaining and updating our awesome open-source projects. You can help us sustain this high-quality of our work by becoming a sponsor on GitHub. Sponsors get numerous benefits in return, see our sponsoring page for details.
Let's take these projects to the next level together! 🚀
Quickstart example
Once installed, you can use the following code to stream messages from any Server-Sent Events (SSE) server endpoint:
data: {"name":"Alice","message":"Hello everybody!"}
data: {"name":"Bob","message":"Hey Alice!"}
data: {"name":"Carol","message":"Nice to see you Alice!"}
data: {"name":"Alice","message":"What a lovely chat!"}
data: {"name":"Bob","message":"All powered by ReactPHP, such an awesome piece of technology :)"}
$es = new Clue\React\EventSource\EventSource('https://example.com/stream.php'); $es->on('message', function (Clue\React\EventSource\MessageEvent $message) { $json = json_decode($message->data); echo $json->name . ': ' . $json->message . PHP_EOL; });
See the examples.
Usage
EventSource
The EventSource class is responsible for communication with the remote Server-Sent Events (SSE) endpoint.
The EventSource object works very similar to the one found in common
web browsers. Unless otherwise noted, it follows the same semantics as defined
under https://html.spec.whatwg.org/multipage/server-sent-events.html
Its constructor simply requires the URL to the remote Server-Sent Events (SSE) endpoint:
$es = new Clue\React\EventSource\EventSource('https://example.com/stream.php');
If you need custom connector settings (DNS resolution, TLS parameters, timeouts,
proxy servers etc.), you can explicitly pass a custom instance of the
ConnectorInterface
to the Browser instance
and pass it as an additional argument to the EventSource like this:
$connector = new React\Socket\Connector([ 'dns' => '127.0.0.1', 'tcp' => [ 'bindto' => '192.168.10.1:0' ], 'tls' => [ 'verify_peer' => false, 'verify_peer_name' => false ] ]); $browser = new React\Http\Browser($connector); $es = new Clue\React\EventSource\EventSource('https://example.com/stream.php', $browser);
This class takes an optional LoopInterface|null $loop parameter that can be used to
pass the event loop instance to use for this object. You can use a null value
here in order to use the default loop.
This value SHOULD NOT be given unless you're sure you want to explicitly use a
given event loop instance.
message event
The message event will be emitted whenever an EventSource message is received.
$es->on('message', function (Clue\React\EventSource\MessageEvent $message) { // $json = json_decode($message->data); var_dump($message); });
The EventSource stream may emit any number of messages over its lifetime. Each
message event will receive a MessageEvent object.
The MessageEvent::$data property can be used to access
the message payload data. It is commonly used for transporting structured data
such as JSON:
data: {"name":"Alice","age":30}
data: {"name":"Bob","age":50}
$es->on('message', function (Clue\React\EventSource\MessageEvent $message) { $json = json_decode($message->data); echo "{$json->name} is {$json->age} years old" . PHP_EOL; });
The EventSource stream may specify an event type for each incoming message. This
event field can be used to emit appropriate event types like this:
data: Alice
event: join
data: Hello!
event: chat
data: Bob
event: leave
$es->on('join', function (Clue\React\EventSource\MessageEvent $message) { echo $message->data . ' joined' . PHP_EOL; }); $es->on('chat', function (Clue\React\EventSource\MessageEvent $message) { echo 'Message: ' . $message->data . PHP_EOL; }); $es->on('leave', function (Clue\React\EventSource\MessageEvent $message) { echo $message->data . ' left' . PHP_EOL; });
See also MessageEvent::$type property for more details.
open event
The open event will be emitted when the EventSource connection is successfully established.
$es->on('open', function () { echo 'Connection opened' . PHP_EOL; });
Once the EventSource connection is open, it may emit any number of
message events.
If the connection can not be opened successfully, it will emit an
error event instead.
error event
The error event will be emitted when the EventSource connection fails.
The event receives a single Exception argument for the error instance.
$redis->on('error', function (Exception $e) { echo 'Error: ' . $e->getMessage() . PHP_EOL; });
The EventSource connection will be retried automatically when it is temporarily
disconnected. If the server sends a non-successful HTTP status code or an
invalid Content-Type response header, the connection will fail permanently.
$es->on('error', function (Exception $e) use ($es) { if ($es->readyState === Clue\React\EventSource\EventSource::CLOSED) { echo 'Permanent error: ' . $e->getMessage() . PHP_EOL; } else { echo 'Temporary error: ' . $e->getMessage() . PHP_EOL; } });
See also the EventSource::$readyState property.
EventSource::$readyState
The int $readyState property can be used to
check the current EventSource connection state.
The state is read-only and can be in one of three states over its lifetime:
EventSource::CONNECTINGEventSource::OPENEventSource::CLOSED
EventSource::$url
The readonly string $url property can be used to
get the EventSource URL as given to the constructor.
close()
The close(): void method can be used to
forcefully close the EventSource connection.
This will close any active connections or connection attempts and go into the
EventSource::CLOSED state.
MessageEvent
The MessageEvent class represents an incoming EventSource message.
MessageEvent::$data
The readonly string $data property can be used to
access the message payload data.
data: hello
assert($message->data === 'hello');
The data field may also span multiple lines. This is commonly used for
transporting structured data such as JSON:
data: {
data: "message": "hello"
data: }
$json = json_decode($message->data); assert($json->message === 'hello');
If the message does not contain a data field or the data field is empty, the
message will be discarded without emitting an event.
MessageEvent::$lastEventId
The readonly string $lastEventId property can be used to
access the last event ID.
data: hello
id: 1
assert($message->data === 'hello'); assert($message->lastEventId === '1');
Internally, the id field will automatically be used as the Last-Event-ID HTTP
request header in case the connection is interrupted.
If the message does not contain an id field, the $lastEventId property will
be the value of the last ID received. If no previous message contained an ID, it
will default to an empty string.
MessageEvent::$type
The readonly string $type property can be used to
access the message event type.
data: Alice
event: join
assert($message->data === 'Alice'); assert($message->type === 'join');
Internally, the event field will be used to emit the appropriate event type.
See also message event.
If the message does not contain a event field or the event field is empty,
the $type property will default to message.
Install
The recommended way to install this library is through Composer. New to Composer?
This project follows SemVer. This will install the latest supported version:
$ composer require clue/reactphp-eventsource:^1
See also the CHANGELOG for details about version upgrades.
This project aims to run on any platform and thus does not require any PHP extensions and supports running on legacy PHP 5.4 through current PHP 8+. It's highly recommended to use the latest supported PHP version for this project.
Tests
To run the test suite, you first need to clone this repo and then install all dependencies through Composer:
$ composer install
To run the test suite, go to the project root and run:
$ vendor/bin/phpunit
License
This project is released under the permissive MIT license.
Did you know that I offer custom development services and issuing invoices for sponsorships of releases and for contributions? Contact me (@clue) for details.
More
-
If you want to learn more about processing streams of data, refer to the documentation of the underlying react/stream component.
-
If you're looking to run the server side of your Server-Sent Events (SSE) application, you may want to use the powerful server implementation provided by Framework X.
wpjscc/reactphp-eventsource 适用场景与选型建议
wpjscc/reactphp-eventsource 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 16 次下载、GitHub Stars 达 0, 最近一次更新时间为 2023 年 02 月 15 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「async」 「event-driven」 「eventsource」 「reactphp」 「sse」 「Server-Side Events」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 wpjscc/reactphp-eventsource 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 wpjscc/reactphp-eventsource 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 wpjscc/reactphp-eventsource 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Библиотека для реализаций паттерна Pub/Sub
Instant real-time updates. Lightweight EventSource client receiving live messages via HTML5 Server-Sent Events (SSE). Fast stream processing built on top of ReactPHP's event-driven architecture.
Rabbitevents common package
The bundle for easy using json-rpc api on your project
Streaming, async HTML5 Server-Sent Events server (aka. SSE or EventSource)
Библиотека для реализаций паттерна Pub/Sub
统计信息
- 总下载量: 16
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 23
- 依赖项目数: 1
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2023-02-15