You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Mule 3.9.0中结合Http Listener与Jersey实现Server-Sent Events(SSE)并保持Socket连接不关闭?

在Mule 3.9.0中用Jersey实现Server-Sent Events(SSE)的解决方案

首先明确回答:完全可以在Mule 3.9.0版本中通过Jersey实现SSE,你遇到的连接被立即关闭的问题,主要是Mule Http Listener的默认超时配置和Jersey SSE特性未正确注册这两个核心原因导致的,下面是具体的解决步骤:

1. 调整Http Listener的连接超时配置

Mule的Http Listener默认有较短的connectionIdleTimeout(默认30秒左右),一旦连接空闲就会主动关闭,这和SSE需要长期保持连接的需求冲突。你需要在http:listener-config里显式设置更长的超时时间,或者设为0表示永不超时:

<http:listener-config name="HttpListenerConfig" host="0.0.0.0" basePath="/myservice" port="8090" connectionIdleTimeout="0" />

注意:设为0在生产环境要谨慎,建议根据业务场景设置一个合理的长超时(比如3600000毫秒=1小时),避免资源泄漏。

2. 确保Jersey SSE特性正确注册

你的当前配置里没有注册Jersey的SseFeature,这会导致SSE响应的头部和流处理逻辑不生效,Mule无法识别SSE的长连接需求。需要修改jersey:resources配置,添加SseFeature的注册:

<flow name="NotificationServiceFlow">
    <http:listener config-ref="HttpListenerConfig" path="/sse/*" allowedMethods="GET" parseRequest="false" responseStreamingMode="ALWAYS">
    </http:listener>
    <jersey:resources>
        <jersey:feature>
            <spring-object bean="org.glassfish.jersey.media.sse.SseFeature"/>
        </jersey:feature>
        <component>
            <spring-object bean="NotificationResource"/>
        </component>
    </jersey:resources>
</flow>

或者你也可以在NotificationResource所在的Spring配置里,创建一个包含SseFeature的ResourceConfig bean,然后直接引用这个bean到jersey:resources中:

<bean id="sseResourceConfig" class="org.glassfish.jersey.server.ResourceConfig">
    <constructor-arg>
        <list>
            <value>com.yourpackage.NotificationResource</value>
            <value>org.glassfish.jersey.media.sse.SseFeature</value>
        </list>
    </constructor-arg>
</bean>

<!-- 然后在flow里替换为: -->
<jersey:resources ref="sseResourceConfig"/>

3. 优化Jersey资源的实现细节

你的NotificationResource实现基本没问题,但可以添加一个关闭监听器避免内存泄漏:

@GET
@Produces(SseFeature.SERVER_SENT_EVENTS)
public EventOutput subscribe() {
    final EventOutput eventOutput = new EventOutput();
    broadcaster.add(eventOutput);
    // 添加关闭监听器,移除失效的eventOutput
    eventOutput.setCloseListener(new EventOutput.CloseListener() {
        @Override
        public void onClose(EventOutput eventOutput) {
            broadcaster.remove(eventOutput);
        }
    });
    return eventOutput;
}

4. 测试连接是否保持打开

可以用curl命令测试:

curl -N http://localhost:8090/myservice/sse/notifications

如果连接保持打开,没有立即断开,就说明配置生效了。此时调用broadcast方法发送消息,curl应该能实时收到。

常见问题排查

  • 如果还是关闭连接,检查Mule的日志,看是否有超时或错误信息
  • 确认没有其他Mule拦截器或过滤器主动关闭连接
  • 确保Jersey的版本和Mule 3.9.0兼容(Mule 3.9.0默认集成的Jersey版本是2.25.1,建议使用对应版本的jersey-media-sse依赖)

内容的提问来源于stack exchange,提问作者William

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 06:44:52