Spring-cloud-gateway: Server Sent Events with spring-cloud-gateway

Created on 16 Jan 2018  路  14Comments  路  Source: spring-cloud/spring-cloud-gateway

I am using spring-cloud-gateway v2.0.0.M5 to proxy another spring boot application that uses Server Sent Events (SSE) to send some notifications to the GUI.

When I hit the notification server directly, it reaches GUI almost immediately after being published. However when I access notification server through spring-cloud-gateway, there is a lag between event publish and being received in the GUI. spring-cloud-gateway server seems to be batching the requests and flushes to the GUI in around a minute or so.

Is there a workaround to disable this behaviour. I don't want a lag in the event publishing and delivery to the GUI. I suspect this is happening because transfer-encoding begin chunked in the response headers.

Access-Control-Allow-Credentials:true
Access-Control-Allow-Origin:http://localhost:63342
Content-Type:text/event-stream;charset=UTF-8
Date:Tue, 16 Jan 2018 01:57:52 GMT
transfer-encoding:chunked
transfer-encoding:chunked
Vary:Origin
X-Application-Context:notification-ms:dev:8030
X-Response-Default-Foo:Default-Bar
bug

All 14 comments

I don't think the gateway is doing it on purpose. That's the default behavior of reactor Netty

Ok. Do we have any workarounds for this?

Are you positive that particular header is the cause?

Not very sure if the header is causing the issue. Same issue was there with zuul too and apparently this header is same in both cases.

What seems to be causing the issue is, gateway flushes the response when SSE emitter completes which is 1 minute in my case. Though it keeps buffering events that SSE Emitter sends meanwhile.

Is there a way to extend this behavior? I thought about redirecting the request first to a local controller and returning an SSE Emitter from there and keep calling send when remote SSE send an event. Does this seem like a reasonable approach?

I'm seeing the same problem on my end.

In my case I have a backend service that emits an event indefinitely every 1 second as a sort of a push heartbeat to the browser. I'm using WebFlux using Spring Boot 2 RC1. Works fine when I make a call directly from the client to the backend service.

However, when I make the call from the client through the gateway the response never comes back. It seems that the gateway is waiting for the backend server to close the socket, yet it never does.

Is there a way to configure the gateway to support SSE?

Turns out it had nothing to do with the header, but properly flushing the response for streaming media types.

Thanks @rstoyanchev for the fix (even if that wasn't the original theory).

I am facing the same issue, can someone explain me how to fix?

@marcoskichel there was a fix in Finchley.RELEASE. If you are using that version, please open a new issue with a project that recreates the problem.

I have implemented SSE cross-domain through this configuration, hoping to help you.

spring:
  cloud:
    gateway:
      routes:
      - id: spider_route
        uri: ws:${proxy.api.url}
        predicates:
        - Path=/**
        filters:
        - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin # If the back-end server also provides cross-domain support, you need to add this.
      globalcors:
        corsConfigurations:
          '[/**]':
            allowedOrigins: "*" 
            allowedMethods:
            - POST
            - GET
            - DELETE
            - PUT
           allowedHeaders: "*" #It is not configured to support simple requests across domains such as GET and DELETE. It is essential for complex requests such as POST SSE requests.

Please learn how to properly format code and logs.

I am facing similar issue, gateway is working fine as expected for all other micro services but in case of sse request it remains in pending state.. gateway receives request and then nothing happens.. note - without gateway sse request to micro service works fine.. I am using Spring Boot v2.2.4.. I have tried different versions as discussed in this post but no success.. issue remains same.. :(

Can anyone please help me on this..?

Below is my application.yml..

spring: cloud: gateway: globalcors: corsConfigurations: '[/**]': allowedOrigins: "*" allowedHeaders: "*" allowedMethods: "*" allowCredentials: true routes: - id: notification uri: lb://MS-NOTIFICATION predicates: - Path=/v1/ms/notification/** filters: - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin

If I change uri scheme from 'lb' to 'ws', gateway returns 400 Bad Request error with message "Invalid 'Upgrade' header: [User-Agent:"PostmanRuntime/7.22.0", Accept:"/", Cache-Control:"no-cache", Postman-Token:"55973ce9-69b3-48c7-ac49-8790e922e257", Host:"localhost:5555", Accept-Encoding:"gzip, deflate, br", Connection:"keep-alive"]""

@munibahmadpk it doesn't seem related. If you think there is a bug, please open a new issue with a project that recreates the problem.

Was this page helpful?
0 / 5 - 0 ratings