Zuul Push Server SSE protocol not working
dkublik opened this issue · 3 comments
When Running Zuul Push Server in SSE (Server Sent Events), Push Protocol is not working correctly.
Problem Description
Messages mentioned below are never received by the client:
goAwayMessage()
serverClosingConnectionMessage()
-
all the calls of
com.netflix.zuul.netty.server.push.PushProtocol.sendErrorAndClose()
-
retry message from
com.netflix.zuul.sample.push.SampleSSEPushClientProtocolHandler.channelRead()
String reconnectInterval = "retry: " + SSE_RETRY_BASE_INTERVAL.get() + "\r\n\r\n";
ctx.writeAndFlush(reconnectInterval);
- more over:
com.netflix.zuul.netty.server.push.PushRegistrationHandler.keepAlive()
will work only for websockets:
if (KEEP_ALIVE_ENABLED.get()) {
this.ctx.writeAndFlush(new PingWebSocketFrame());
}
Cause Explanation
This is because all of theses message are sent as String messages, and as such will be ignored by HttpObjectEncoder.write()
(which is called by io.netty.handler.codec.http.HttpServerCodec
set in com.netflix.zuul.netty.server.push.PushChannelInitializer
)
HttpObjectEncoder.write()
accepts only following types
io.netty.handler.codec.http.FullHttpMessage
io.netty.handler.codec.http.HttpMessage
io.netty.handler.codec.http.LastHttpContent
io.netty.handler.codec.http.HttpContent
io.netty.buffer.ByteBuf
io.netty.channel.FileRegion
so all not working protocol messages should be probably sent as ByteBuf
(just like com.netflix.zuul.netty.server.push.PushProtocol.SSE.sendPushMessage()
which works)
How to Replicate
- Launch Zuul Push Server
- set
SampleServerStartup.SERVER_TYPE
toSSE
- run
Bootstrap.main()
- In first terminal window register to the Push Server with user ala:
curl -v "http://localhost:7001/sse" \
--header 'Accept: text/event-stream' \
-b 'userAuthCookie=ala'
- In the second terminal window send message to user ala:
curl -v http://localhost:7008/push \
--header 'X-CUSTOMER_ID: ala' \
-d 'message to ala'
observe (in first terminal window) that no protocol messages are received (for example missing message "retry" below):
kublikd@J4MJ4HHYH3 push-server % curl -v "http://localhost:7001/sse" \
--header 'Accept: text/event-stream' \
-b 'userAuthCookie=ala'
* Host localhost:7001 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
* Trying [::1]:7001...
* Connected to localhost (::1) port 7001
> GET /sse HTTP/1.1
> Host: localhost:7001
> User-Agent: curl/8.6.0
> Cookie: userAuthCookie=ala
> Accept: text/event-stream
>
< HTTP/1.1 200 OK
< Connection: keep-alive
< Content-Type: text/event-stream
< Transfer-Encoding: chunked
<
event: push
data: message to alice
should be:
kublikd@J4MJ4HHYH3 push-server % curl -v "http://localhost:7001/sse" \
--header 'Accept: text/event-stream' \
-b 'userAuthCookie=ala'
* Host localhost:7001 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
* Trying [::1]:7001...
* Connected to localhost (::1) port 7001
> GET /sse HTTP/1.1
> Host: localhost:7001
> User-Agent: curl/8.6.0
> Cookie: userAuthCookie=ala
> Accept: text/event-stream
>
< HTTP/1.1 200 OK
< Connection: keep-alive
< Content-Type: text/event-stream
< Transfer-Encoding: chunked
<
retry: 5000
event: push
data: message to alice
other messages (mentioned in the first paragraph will also be missing)