php-opcua/opcua-client-ext-transport-pubsub
Composer 安装命令:
composer require php-opcua/opcua-client-ext-transport-pubsub
包简介
OPC UA PubSub Subscriber for PHP — UDP + UADP + JSON, extends opcua-client
关键字:
README 文档
README
Subscribe to OPC UA PubSub streams directly from PHP — UDP unicast or multicast, UADP and JSON payloads, group-key security — without any C/C++ extensions, HTTP gateways, or middleware in between.
This package extends php-opcua/opcua-client with the OPC UA Part 14 — PubSub Subscriber role. The core client stays unchanged; installing this extension only adds the PhpOpcua\Client\ExtTransportPubSub\* namespace. Same zero-dependency philosophy, same PSR-3 / PSR-14 integration, same cross-platform support.
What you can do with it:
- Listen to PubSub NetworkMessages over UDP unicast or multicast
- Decode UADP binary and JSON payloads into typed DataSetMessages with named fields
- Verify and decrypt signed and encrypted PubSub streams using pre-shared group keys or a Security Key Service
- Configure readers by
(publisherId, writerGroupId, dataSetWriterId)and let the kernel demux incoming traffic - React in real time via PSR-14 events or plain callbacks on every decoded field
All this with ext-sockets as the only extension beyond the core's ext-openssl, and PHP 8.2 through 8.5 supported on Linux, macOS, and Windows.
Note: PubSub is a fire-and-forget broadcast paradigm, not a session-oriented protocol. A long-running worker process (ReactPHP, Symfony Messenger, Laravel queue worker, Artisan command, systemd unit) is the natural place to run a
Subscriber. Short-lived PHP requests cannot sustain a meaningful subscription window.
Quick Start
composer require php-opcua/opcua-client-ext-transport-pubsub
use PhpOpcua\Client\ExtTransportPubSub\SubscriberBuilder; use PhpOpcua\Client\ExtTransportPubSub\Types\DataSetMessage; use PhpOpcua\Client\ExtTransportPubSub\Types\DataSetMetaData; use PhpOpcua\Client\ExtTransportPubSub\Types\DataSetReaderConfig; $metadata = DataSetMetaData::fromJsonFile('/etc/opcua/line1.json'); $subscriber = SubscriberBuilder::create() ->onDataSetMessage(function (DataSetMessage $msg) { foreach ($msg->fields as $field) { echo "{$field->name} = {$field->getScalar()}\n"; } }) ->listenUdp( endpoint: 'opc.udp://239.0.0.1:4840', readers: [ new DataSetReaderConfig( publisherId: 100, writerGroupId: 1, dataSetWriterId: 1, dataSetMetaData: $metadata, ), ], ); $subscriber->run();
That's it. Build, configure one reader, block on run(). Press Ctrl-C (or call stop() from a signal handler) to exit cleanly.
Tip: Prefer
poll(timeoutMs: 500)overrun()when you have your own event loop (ReactPHP, Amp, custom). It returns the batch of decodedDataSetMessageobjects from this tick without blocking past the timeout.
See It in Action
Listen on unicast UDP
$subscriber = SubscriberBuilder::create() ->listenUdp( endpoint: 'opc.udp://192.168.1.50:4840', readers: [$reader], );
Tune the UDP socket
use PhpOpcua\Client\ExtTransportPubSub\Transport\UdpOptions; $subscriber = SubscriberBuilder::create() ->listenUdp( endpoint: 'opc.udp://239.0.0.1:4840', transport: new UdpOptions( interface: '0.0.0.0', receiveBufferSize: 131072, ttl: 8, reuseAddress: true, ), readers: [$reader], );
Decode JSON payloads
$subscriber = SubscriberBuilder::create() ->useJson() ->listenUdp( endpoint: 'opc.udp://239.0.0.1:4840', readers: [$reader], );
Load metadata from JSON, XML, or a live server
use PhpOpcua\Client\ExtTransportPubSub\Types\DataSetMetaData; // From a JSON config file $metadata = DataSetMetaData::fromJsonFile('/etc/opcua/line1.json'); // From an OPC UA DataSetMetaDataType XML file $metadata = DataSetMetaData::fromXmlFile('/etc/opcua/line1.xml'); // From a running server via the classic opcua-client $metadata = DataSetMetaData::fetchFromServer($client, 'ns=2;s=PDS/Line1/Metadata');
Secure the stream with pre-shared keys
use PhpOpcua\Client\ExtTransportPubSub\Security\PubSubSecurityMode; use PhpOpcua\Client\ExtTransportPubSub\Security\PubSubSecurityOptions; use PhpOpcua\Client\ExtTransportPubSub\Security\StaticGroupKeyProvider; $subscriber = SubscriberBuilder::create() ->listenUdp( endpoint: 'opc.udp://239.0.0.1:4840', security: new PubSubSecurityOptions( mode: PubSubSecurityMode::SignAndEncrypt, keyProvider: new StaticGroupKeyProvider( signingKey: hex2bin($_ENV['PUBSUB_SIGN']), encryptingKey: hex2bin($_ENV['PUBSUB_ENC']), keyNonce: hex2bin($_ENV['PUBSUB_NONCE']), ), ), readers: [$reader], );
Rotate keys from a Security Key Service
use PhpOpcua\Client\ClientBuilder; use PhpOpcua\Client\ExtTransportPubSub\Security\SksGroupKeyProvider; $client = ClientBuilder::create()->connect('opc.tcp://sks.example.com:4840'); $provider = new SksGroupKeyProvider($client, securityGroupId: 'line1-ops'); $provider->refresh(); $subscriber = SubscriberBuilder::create() ->listenUdp( endpoint: 'opc.udp://239.0.0.1:4840', security: new PubSubSecurityOptions(PubSubSecurityMode::SignAndEncrypt, $provider), readers: [$reader], );
Poll instead of run
while (! $shouldStop) { foreach ($subscriber->poll(timeoutMs: 250) as $msg) { handle($msg); } doOtherWork(); }
Graceful shutdown from a signal handler
pcntl_async_signals(true); pcntl_signal(SIGTERM, fn () => $subscriber->stop()); pcntl_signal(SIGINT, fn () => $subscriber->stop()); $subscriber->run();
Receive PSR-14 events for every step
use PhpOpcua\Client\ExtTransportPubSub\Event\DataSetFieldReceived; use PhpOpcua\Client\ExtTransportPubSub\Event\MessageDecodeError; use PhpOpcua\Client\ExtTransportPubSub\Event\SecurityValidationFailed; $subscriber = SubscriberBuilder::create() ->setEventDispatcher($yourDispatcher) ->listenUdp(/* ... */);
Listeners fire for NetworkMessageReceived, DataSetMessageReceived, DataSetFieldReceived, MessageDecodeError, SecurityValidationFailed, TransportOpened, TransportClosed, and TransportError. Zero overhead when no dispatcher is configured.
Add structured logging
use Monolog\Logger; use Monolog\Handler\StreamHandler; $logger = new Logger('pubsub'); $logger->pushHandler(new StreamHandler('php://stderr', Logger::DEBUG)); $subscriber = SubscriberBuilder::create() ->setLogger($logger) ->listenUdp(/* ... */);
Any PSR-3 logger works. Without one, logging is silently disabled.
Plug in your own transport
use PhpOpcua\Client\ExtTransportPubSub\Transport\PubSubTransportInterface; class MyKafkaTransport implements PubSubTransportInterface { /* ... */ } $subscriber = SubscriberBuilder::create() ->listenOn( transports: [new MyKafkaTransport(/* ... */)], readers: [$reader], );
The PubSubTransportInterface contract is the extension point that keeps the subscriber agnostic to the underlying transport. External packages like php-opcua/opcua-client-ext-mqtt plug in by implementing this interface.
Why This Package?
- Zero runtime dependencies beyond the core —
ext-socketsplus the core'sext-openssl. Optional PSR-3 logging and PSR-14 events via any compatible implementation. - PHP 8.2+ — runs on any modern PHP.
- Native UADP binary — speaks the OPC UA binary PubSub encoding directly over UDP. No translation layer.
- UDP unicast and multicast — IGMP group join with
MCAST_JOIN_GROUPplus legacyIP_ADD_MEMBERSHIPfallback. TTL, buffer size, andSO_REUSEADDRexposed as first-class options. - JSON codec included — the reversible form from Part 14 §7.2, round-trippable without external metadata.
- Group-key security — HMAC-SHA256 signing and AES-256-CBC encryption handled in pure PHP via
ext-openssl. Pre-shared keys or live rotation from a Security Key Service. - Metadata any way you like — PHP arrays, JSON files,
DataSetMetaDataTypeXML exports, or a live read from the publishing server. - Typed everywhere — every DTO uses
public readonlyproperties. No arrays, no magic. - Cross-platform — tested on Linux, macOS, and Windows across PHP 8.2–8.5. No FFI, no COM, no platform-specific APIs beyond
ext-sockets. - Does not modify the core —
ClientBuilder,Client,ClientKernel,OpcUaClientInterfaceare untouched.
Features
| Feature | What it does |
|---|---|
| UDP Transport | Unicast and IPv4 multicast with MCAST_JOIN_GROUP (legacy fallback), SO_REUSEADDR, non-blocking sockets, socket_select timeout |
| UADP Codec | Binary PubSub encoding — PublisherId (Byte/UInt16/UInt32/UInt64/String), GroupHeader, PayloadHeader with multiple DataSetMessages, Variant / RawData / DataValue field encodings |
| JSON Codec | Reversible JSON encoding from Part 14 §7.2 (encode + decode, no external metadata required) |
| Subscriber Runtime | Event loop over N transports, demux by (publisherId, writerGroupId, dataSetWriterId), blocking run() and non-blocking poll() |
| Security | Sign (HMAC-SHA256) and SignAndEncrypt (AES-256-CBC) with pre-shared keys via StaticGroupKeyProvider or SKS-backed rotation via SksGroupKeyProvider |
| Metadata Loaders | DataSetMetaData::fromArray(), fromJsonFile(), fromXmlFile(), fromXmlString(), fromBinary(), fetchFromServer() |
| PSR-14 Events | NetworkMessageReceived, DataSetMessageReceived, DataSetFieldReceived, MessageDecodeError, SecurityValidationFailed, TransportOpened, TransportClosed, TransportError |
| PSR-3 Logging | Any PSR-3 logger plugs in. NullLogger by default. |
| Pluggable Transports | PubSubTransportInterface is the stable hook point for third-party transports (e.g. MQTT) |
| Module System | PubSubModule base class lets you extend the kernel with custom behaviour (telemetry, alarm forwarding, ...) |
| Typed DTOs | public readonly properties everywhere — NetworkMessage, DataSetMessage, DataSetField, FieldMetaData, DataSetMetaData, DataSetReaderConfig, UdpOptions, ReceivedPayload, PubSubSecurityOptions |
Documentation
Full docs live under docs/ (published at https://www.php-opcua.com/documentation/opcua-client-ext-transport-pubsub).
| Document | Covers |
|---|---|
| Overview | What it is, when to use it, what ships |
| Quick start | Reader + callback + listen, in three steps |
| How it works | The transport → codec → security → kernel pipeline |
| Encodings | UADP and JSON, field encodings |
| Subscriber & builder | Builder, run() / poll() / stop(), lifecycle |
| Transports | UDP configuration, multicast, custom transports |
| Readers & metadata | DataSetReaderConfig, loading DataSetMetaData |
| Modules / Events | Custom kernel hooks; the 8 PSR-14 events |
| Group-key security | Sign, SignAndEncrypt, static keys, SKS rotation |
| Testing · Exceptions | Fake transport + dispatcher; error reference |
Testing
Run ./vendor/bin/pest after composer install. Unit tests cover codec round-trips, UDP loopback send/receive, kernel demux, security unwrap, metadata loaders, and SKS key fetching. CI runs on PHP 8.2, 8.3, 8.4, and 8.5 across Linux, macOS, and Windows via GitHub Actions.
./vendor/bin/pest # everything ./vendor/bin/pest tests/Unit/ # unit only ./vendor/bin/pest tests/Integration/ --group=integration # integration only
Ecosystem
| Package | Description |
|---|---|
| opcua-client | Pure PHP OPC UA client (required) |
| opcua-client-ext-transport-pubsub | OPC UA PubSub Subscriber (this package) |
| opcua-client-nodeset | Pre-generated PHP types from OPC Foundation companion specifications |
| opcua-session-manager | Daemon-based session persistence for the classic client |
| laravel-opcua | Laravel integration for the classic client |
| opcua-cli | CLI tool — browse, read, write, watch, manage certificates |
Community
Have questions, ideas, or want to share what you've built? Join the GitHub Discussions.
Connected a PubSub-capable device? We're collecting a community-driven list of tested publishers. Share your experience — even a one-liner like "open62541 1.4, UDP multicast, works fine" helps other users know what to expect.
AI-Ready
This package ships with machine-readable documentation designed for AI coding assistants (Claude, Cursor, Copilot, ChatGPT, and others). Feed these files to your AI so it knows how to use the library correctly:
| File | Purpose |
|---|---|
llms.txt |
Compact project summary — architecture, key classes, API signatures |
llms-full.txt |
Comprehensive technical reference — every class, DTO, encoding detail |
llms-skills.md |
Task-oriented recipes — step-by-step instructions for common tasks |
How to use: copy the files you need into your project's AI configuration directory. The files are located in vendor/php-opcua/opcua-client-ext-transport-pubsub/ after composer install.
- Claude Code: reference per-session with
--add-file vendor/php-opcua/opcua-client-ext-transport-pubsub/llms-skills.md - Cursor: copy into your project's rules directory —
cp vendor/php-opcua/opcua-client-ext-transport-pubsub/llms-skills.md .cursor/rules/opcua-pubsub.md - GitHub Copilot: copy or append into
.github/copilot-instructions.md - Other tools: paste the content into your system prompt or project knowledge base
Roadmap
See ROADMAP.md for what's coming next.
Contributing
Contributions welcome — see CONTRIBUTING.md.
Changelog
See CHANGELOG.md.
License
php-opcua/opcua-client-ext-transport-pubsub 适用场景与选型建议
php-opcua/opcua-client-ext-transport-pubsub 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 0 次下载、GitHub Stars 达 0, 最近一次更新时间为 2026 年 06 月 09 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「udp」 「subscriber」 「pubsub」 「publish-subscribe」 「multicast」 「IIoT」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 php-opcua/opcua-client-ext-transport-pubsub 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 php-opcua/opcua-client-ext-transport-pubsub 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 php-opcua/opcua-client-ext-transport-pubsub 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Simple, event-driven multicast UDP message client and server for ReactPHP.
Queue
Библиотека для реализаций паттерна Pub/Sub
Библиотека для реализаций паттерна Pub/Sub
The Listener component of the RabbitEvents library.
The Publisher component of the RabbitEvents package.
统计信息
- 总下载量: 0
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 42
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-06-09