Spring tomcat老项目使用SseEmitter无法建立连接问题解决

背景:最近需要在公司老项目里加入Sse实现服务端给客户端推送消息的功能。因为无需双端通信,所以也就选择了Sse没用WebSocket。

Spring和SpringMVC的版本是4.2.4.RELEASE,JDK为1.7,tomcat为7.0.90。

	<spring.version>4.2.4.RELEASE</spring.version>
	
	...
	
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-web</artifactId>
		<version>${spring.version}</version>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-webmvc</artifactId>
		<version>${spring.version}</version>
	</dependency>

这是Controller的连接接口。

    @RequestMapping("/connect")
    public SseEmitter connect() {
        //默认是30s超时,设置为0L永不超时
        SseEmitter sseEmitter = new SseEmitter(0L);
        // ...
        return sseEmitter;
    }

发起请求后,后端正常返回SseEmitter无报错,但前端却一直连接不上(使用Apifox进行测试)。
在这里插入图片描述
在这里插入图片描述
把连接接口直接复制,放到SpringBoot中,直接请求就连接成功。(因为SpringBoot自动开启了异步支持)
在这里插入图片描述
在网上搜SSE、SseEmitter,都只是写着如何使用,没有说配置相关的。(还是对SpringMVC不了解导致的)

后面实在解决不了,换成DeferredResult使用,直接报错提示Request processing failed; nested exception is java.lang.IllegalStateException: Async support must be enabled on a servlet and for all filters involved in async request processing. This is done in Java code using the Servlet API or by adding "<async-supported>true</async-supported>" to servlet and filter declarations in web.xml.。(需要把web.xml中的<error-code>500</error-code>注释掉才能看到)
在这里插入图片描述
到这里,才知道web.xml里没开启对异步的支持。对web.xml中的<servlet><filter><filter-mapping>都加上对异步的支持。(多个filter最好都加上)

<async-supported>true</async-supported>

<dispatcher>ASYNC</dispatcher>
	<servlet>
		<servlet-name>spring</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>/WEB-INF/spring-servlet.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
		<async-supported>true</async-supported>
	</servlet>
	
	<filter>
		<filter-name>encodingFilter</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<async-supported>true</async-supported>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>utf8</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>encodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
		<dispatcher>ASYNC</dispatcher>
	</filter-mapping>
	...

重启后,DeferredResult可以成功连接了,换成SseEmitter也可以重新连接了。(记得把<error-code>500</error-code>注释去掉)
在这里插入图片描述
在这里插入图片描述

Sse的使用可以看看这篇文章:https://juejin.cn/post/7373669988388339723?searchId=202406241455318222F3C07D510A2B8FED

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值