[BUG] GRPC Streaming message frames are not parsed explicitly
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 45/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Stale
- Tech stack
- grpc, php
- Domain
- api, backend, distributed-systems
Research direction
Start by reading Parser::deserializeMessage() and the proposed Parser::parseStreamMessage() entry point in the gRPC component, then trace how streaming responses are received. Confirm how buffers containing multiple length-prefixed messages and stream-ending nonzero gRPC statuses are handled. Done means streaming responses preserve every message and report the final gRPC status correctly, with coverage for both behaviors.
Written by the indexing model from the issue text.
Description
Execute the command and paste the result below.
Command: uname -a && php -v && composer info | grep hyperf && php --ri swoole
uname -a && php -v && composer info | grep hyperf && php --ri swoole
Linux 3dd7ae510298 6.8.0-64-generic #67-Ubuntu SMP PREEMPT_DYNAMIC Sun Jun 15 20:23:40 UTC 2025 aarch64 GNU/Linux
PHP 8.4.16 (cli) (built: Jan 6 2026 20:21:19) (ZTS)
Copyright (c) The PHP Group
Zend Engine v4.4.16, Copyright (c) Zend Technologies
dmcz/hyperf-rocketmq dev-main 358e33c
hyperf/cache 3.1.63 A cache component for hyperf.
hyperf/code-parser 3.1.63 A code parser component for Hyperf.
hyperf/codec 3.1.63 A codec component for Hyperf.
hyperf/collection 3.1.64 Hyperf Collection package which come from illuminate/collections
hyperf/command 3.1.64 Command for hyperf
hyperf/conditionable 3.1.63 Hyperf Macroable package which come from illuminate/conditionable
hyperf/config 3.1.63 An independent component that provides configuration container.
hyperf/context 3.1.63 A coroutine/application context library.
hyperf/contract 3.1.63 The contracts of Hyperf.
hyperf/coordinator 3.1.63 Hyperf Coordinator
hyperf/coroutine 3.1.63 Hyperf Coroutine
hyperf/database 3.1.63 A flexible database library.
hyperf/db-connection 3.1.63 A hyperf db connection handler for hyperf/database.
hyperf/devtool 3.1.63 A Devtool for Hyperf.
hyperf/di 3.1.63 A DI for Hyperf.
hyperf/dispatcher 3.1.63 A HTTP Server for Hyperf.
hyperf/engine 2.14.1 Coroutine engine provided by swoole.
hyperf/engine-contract 1.13.0 Contract for Coroutine Engine
hyperf/event 3.1.63 an event manager that implements PSR-14.
hyperf/exception-handler 3.1.63 Exception handler for hyperf
hyperf/filesystem 3.1.63 flysystem integration for hyperf
hyperf/framework 3.1.63 A coroutine framework that focuses on hyperspeed and flexible, specifically use for build microservices and middlewares.
hyperf/grpc dev-master 1b4f1ed A GRPC basic library for Hyperf.
hyperf/grpc-client dev-master 05c767f A GRPC Client for Hyperf.
hyperf/guzzle 3.1.63 Swoole coroutine handler for guzzle
hyperf/http-message 3.1.63 microservice framework base on swoole
hyperf/http-server 3.1.63 A HTTP Server for Hyperf.
hyperf/laminas-mime 3.0.0 Create and parse MIME messages and parts
hyperf/logger 3.1.63 A logger component for hyperf.
hyperf/macroable 3.1.63 Hyperf Macroable package which come from illuminate/macroable
hyperf/memory 3.1.63 An independent component that use to operate and manage memory.
hyperf/model-listener 3.1.63 A model listener for Hyperf.
hyperf/pipeline 3.1.63 Hyperf Macroable package which come from illuminate/pipeline
hyperf/pool 3.1.63 An independent universal connection pool component.
hyperf/process 3.1.63 A process component for hyperf.
hyperf/redis 3.1.63 A redis component for hyperf.
hyperf/serializer 3.1.63 A serializer component for Hyperf.
hyperf/server 3.1.63 A base server library for Hyperf.
hyperf/snowflake 3.1.63 A snowflake library
hyperf/stdlib 3.1.63 A stdlib component for Hyperf.
hyperf/stringable 3.1.63 Hyperf Stringable package which come from illuminate/support
hyperf/support 3.1.63 A support component for Hyperf.
hyperf/tappable 3.1.63 Hyperf Macroable package which come from illuminate/tappable
hyperf/testing 3.1.63 Testing for hyperf
hyperf/translation 3.1.63 An independent translation component, forked by illuminate/translation.
hyperf/validation 3.1.64 hyperf validation
swoole
Swoole => enabled
Author => Swoole Team <[email protected]>
Version => 6.1.5
Built => Jan 6 2026 20:30:22
host byte order => little endian
coroutine => enabled with boost asm context
epoll => enabled
eventfd => enabled
thread => enabled
signalfd => enabled
cpu_affinity => enabled
spinlock => enabled
rwlock => enabled
openssl => OpenSSL 3.5.4 30 Sep 2025
dtls => enabled
http2 => enabled
json => enabled
curl-native => enabled
curl-version => 8.14.1
c-ares => 1.34.5
zlib => 1.3.1
brotli => E16781312/D16781312
mutex_timedlock => enabled
pthread_barrier => enabled
futex => enabled
execinfo => enabled
Directive => Local Value => Master Value
swoole.enable_library => On => On
swoole.enable_fiber_mock => Off => Off
swoole.enable_preemptive_scheduler => Off => Off
swoole.display_errors => On => On
swoole.use_shortname => Off => Off
swoole.unixsock_buffer_size => 8388608 => 8388608
Description:
当前 streaming RPC 的处理存在两个问题:
- Streaming message 没有按 gRPC message framing 解析在 streaming RPC 中,一个 HTTP/2 DATA frame 中可能包含 多个 gRPC message。根据 gRPC over HTTP/2 协议,每个 message 的格式为:
因此实现需要按 gRPC message framing 从 buffer 中解析 message,而不能依赖 HTTP/2 DATA frame 的边界。当前实现中 Parser::deserializeMessage() 并没有按照 gRPC message framing 对 buffer 再次拆解 frame,因此在streaming RPC 场景下:如果一个 buffer 中包含多个 message,当前实现只会解析出 第一条消息,剩余消息会被忽略。在 unary RPC 场景下通常不会暴露这个问题,因为 unary 语义上只返回一个 message。> DATA frame boundaries have no relation to Length-Prefixed-Message boundaries. Compressed-Flag (1 byte) Message-Length (4 bytes) Message-Payload - Stream 结束时没有检查 gRPC status,因此服务端返回的非 0 状态可能会被忽略。
理论上更合理的做法是修改 Parser::deserializeMessage(),使其按照 gRPC message framing 解析 buffer 并支持多个 message。但改动范围相对较大,另外由于返回数据多为[message|string, grpc-status, resp] 不好追踪需要多测试。因此我目前的修复方式是新增 Parser::parseStreamMessage(),仅在 streaming 场景中使用,从而仅在streaming recv 行为上产生 BC,用于快速修复。
另外当前 gRPC 组件中很多方法直接返回数组结构,对外暴露了协议细节也增加后续维护成本。这里是否有考虑做封装和优化?
Steps To Reproduce:
- Dominant language
- PHP
- Stars
- 6.9k
- Forks
- 1.3k
- Avg merge
- 1h 17m
- Merged PRs (30d)
- 3
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from hyperf/hyperf
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 63/100
-
[BUG] Hyperf\Crontab\Strategy->Executor->floatDiffInRealSeconds deprecatePossibly taken @sneycampos claimed this 20 days ago. Openbug
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
-
question
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
-
支持whereLike等方法Open
Difficulty 3/5 1-2 days Newbie friendliness 52/100
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 79/100
Maintainers usually reply within 1 day
-
bug
Difficulty 1/5 Under an hour Newbie friendliness 84/100
mailcow/mailcow-dockerized#7652 · 2 comments ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Maintainers usually reply within 3 days
-
Difficulty 1/5 Under an hour Newbie friendliness 91/100
benjaminkott/bootstrap_package#1675 ·
-
sync-en
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
Maintainers usually reply within 1 day