Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring WebSocket-控制器发送消息后丢失_Java_Spring_Spring Websocket - Fatal编程技术网

Java Spring WebSocket-控制器发送消息后丢失

Java Spring WebSocket-控制器发送消息后丢失,java,spring,spring-websocket,Java,Spring,Spring Websocket,我遇到了一个问题,SpringWebSocket版本4.1.1.RELEASE无法发送WebSocket消息。并不是每封邮件都会发生这种情况,只是有些邮件因为我不理解的原因而没有发送。消息的内容需要一些时间才能加载,但我不确定这是否是问题的原因,因为有时它可以工作,但大多数时候它不能 我的web应用程序成功订阅了一个频道/user/queue/overview/reqinfo/events,然后发送四条消息请求信息。我的控制器类通过SpringDataJPA和Hibernate在数据库上激发CO

我遇到了一个问题,SpringWebSocket版本4.1.1.RELEASE无法发送WebSocket消息。并不是每封邮件都会发生这种情况,只是有些邮件因为我不理解的原因而没有发送。消息的内容需要一些时间才能加载,但我不确定这是否是问题的原因,因为有时它可以工作,但大多数时候它不能

我的web应用程序成功订阅了一个频道
/user/queue/overview/reqinfo/events
,然后发送四条消息请求信息。我的控制器类通过SpringDataJPA和Hibernate在数据库上激发COUNT()语句,并将结果作为消息返回给请求来自的用户。所有四条消息都由相同的控制器方法处理,但只有两条响应被传递给发送方。我从Spring日志中提取了相关信息,并将它们附在这里。如您所见,
SimpleBrokerMessageHandler
没有处理最后两条消息,因此不会发送给用户。创建这些消息的内容需要一分钟以上的时间

12:50:54,953 DEBUG clientInboundChannel-12 user.UserDestinationMessageHandler:187 - Translated /user/queue/overview/reqinfo/events -> [/queue/overview/reqinfo/events-user8178efnd]
12:50:54,953 DEBUG clientInboundChannel-12 broker.SimpleBrokerMessageHandler:175 - Processing SUBSCRIBE /queue/overview/reqinfo/events-user8178efnd id=sub-7 session=8178efnd
[...]
12:50:54,957 DEBUG clientInboundChannel-2 support.SimpAnnotationMethodMessageHandler:348 - Searching methods to handle SEND /app/overview/reqinfo/events session=8178efnd
12:50:54,957 DEBUG clientInboundChannel-1 support.SimpAnnotationMethodMessageHandler:348 - Searching methods to handle SEND /app/overview/reqinfo/events session=8178efnd
12:50:54,957 DEBUG clientInboundChannel-16 support.SimpAnnotationMethodMessageHandler:348 - Searching methods to handle SEND /app/overview/reqinfo/events session=8178efnd
12:50:54,959 DEBUG clientInboundChannel-10 support.SimpAnnotationMethodMessageHandler:348 - Searching methods to handle SEND /app/overview/reqinfo/events session=8178efnd
[...]
12:50:54,959 DEBUG clientInboundChannel-16 support.SimpAnnotationMethodMessageHandler:446 - Invoking de.d.i.g.websocket.OverviewController#requestOverviewEvents[2 args]
12:50:54,959 DEBUG clientInboundChannel-10 support.SimpAnnotationMethodMessageHandler:446 - Invoking de.d.i.g.websocket.OverviewController#requestOverviewEvents[2 args]
12:50:54,959 DEBUG clientInboundChannel-2 support.SimpAnnotationMethodMessageHandler:446 - Invoking de.d.i.g.websocket.OverviewController#requestOverviewEvents[2 args]
12:50:54,959 DEBUG clientInboundChannel-1 support.SimpAnnotationMethodMessageHandler:446 - Invoking de.d.i.g.websocket.OverviewController#requestOverviewEvents[2 args]
[...]
12:50:55,006 DEBUG clientInboundChannel-1 websocket.OverviewController:196 - requestOverviewEvents, incoming message: MsgOverviewEventsRequest(timeframe=THIS_WEEK)
12:50:55,006 DEBUG clientInboundChannel-10 websocket.OverviewController:196 - requestOverviewEvents, incoming message: MsgOverviewEventsRequest(timeframe=LAST_WEEK)
12:50:55,006 DEBUG clientInboundChannel-2 websocket.OverviewController:196 - requestOverviewEvents, incoming message: MsgOverviewEventsRequest(timeframe=YESTERDAY)
12:50:55,006 DEBUG clientInboundChannel-16 websocket.OverviewController:196 - requestOverviewEvents, incoming message: MsgOverviewEventsRequest(timeframe=TODAY)
[...]
12:50:55,032 DEBUG clientInboundChannel-16 websocket.OverviewController:225 - requestOverviewEvents, outgoing message: MsgOverviewEvents(timeframe=TODAY, count=31, error=false)
12:50:55,035 DEBUG clientInboundChannel-16 broker.SimpleBrokerMessageHandler:152 - Processing MESSAGE destination=/queue/overview/reqinfo/events-user8178efnd session=null payload={"timeframe":"TODAY","count":31,"error":false}
12:50:55,035 DEBUG clientInboundChannel-16 broker.SimpleBrokerMessageHandler:196 - Broadcasting to 1 sessions.
[...]
12:51:01,018 DEBUG clientInboundChannel-2 websocket.OverviewController:225 - requestOverviewEvents, outgoing message: MsgOverviewEvents(timeframe=YESTERDAY, count=190292, error=false)
12:51:01,020 DEBUG clientInboundChannel-2 broker.SimpleBrokerMessageHandler:152 - Processing MESSAGE destination=/queue/overview/reqinfo/events-user8178efnd session=null payload={"timeframe":"YESTERDAY","count":190292,"error":false}
12:51:01,020 DEBUG clientInboundChannel-2 broker.SimpleBrokerMessageHandler:196 - Broadcasting to 1 sessions.
[...]
12:51:19,081 DEBUG clientInboundChannel-1 websocket.OverviewController:225 - requestOverviewEvents, outgoing message: MsgOverviewEvents(timeframe=THIS_WEEK, count=845956, error=false)
12:51:19,088 DEBUG clientInboundChannel-10 websocket.OverviewController:225 - requestOverviewEvents, outgoing message: MsgOverviewEvents(timeframe=LAST_WEEK, count=1421118, error=false)
这是一个经常出现问题的示例案例。我有其他视图,其中包含其他受到相同问题影响的消息和控制器,它们的消息不需要一分钟就可以生成,只需要几秒钟甚至更短的时间。我正在使用带有SockJS支持的
SimpleMessageBroker
(使用SockJS 0.3.4)。在尝试修复此问题时,我将此bean添加到我的WebSocket配置类中,以手动设置connecton上的超时,但它没有解决问题:

@Bean
public ServletServerContainerFactoryBean createWebSocketContainer() {
    long tenMinutesInMillis = 10 * 60 * 1000;

    ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
    container.setAsyncSendTimeout(tenMinutesInMillis);
    container.setMaxSessionIdleTimeout(tenMinutesInMillis);

    return container;
}
为什么有些消息被丢弃,而另一些消息被正确发送?如果您需要日志或源代码中的更多信息,请询问

[更新]有关该行为的一些附加信息:

计数项目数最少的第一条消息始终返回。第二条消息大部分时间返回,最后两条消息大约90%的时间无法发送。加载失败后,其他视图也不会加载,响应消息不会发送到web界面,即使订阅已被接收和处理。在浏览器中点击刷新以重新加载页面后,一切正常,直到消息再次被卡住

然而,在后台运行并使用WebSocket向用户发送消息的heartbeat系统一直在工作。它似乎完全不受这个问题的影响

[更新2]

当问题发生时,
sockJsScheduler
似乎没有处理所有请求。
WebSocketMessageBrokerStats
记录的信息消息给出以下输出:

INFO MessageBrokerSockJS-2 config.WebSocketMessageBrokerStats:113 - WebSocketSession[1 current WS(1)-HttpStream(0)-HttpPoll(0), 1 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(1)-CONNECTED(1)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 16, active threads = 0, queued tasks = 0, completed tasks = 120], outboundChannelpool size = 16, active threads = 0, queued tasks = 0, completed tasks = 16], sockJsScheduler[pool size = 8, active threads = 1, queued tasks = 4, completed tasks = 18]

它表示,
sockJsScheduler
有四个排队的任务没有被处理,也许这些消息没有正确发送?不幸的是,日志中没有关于为什么不处理它们的进一步信息。

在对我的应用程序,特别是处理该行为的Spring代码进行了大量调试之后,我找到了这种行为的原因

问题既不是控制器,也不是Spring内部进程,而是我在Spring安全身份验证期间用于主体对象的类。它存储用户成功应答的最后一个心跳ID,以检查向系统发送消息的用户是否处于活动状态或会话是否已被视为已死亡。该ID包含在该对象的
equals()
hashCode()
toString()
方法中

Spring使用其中一种方法(经过一些测试,我猜它是
toString()
,在我看来这不是一个好的选择)来翻译
@SendToUser
操作的目标路径。如果字符串发生变化(当响应新的心跳ID时,我的应用程序就是这样),Spring将无法转换目标路径,并且不会发送消息。说明这一点的日志条目作为跟踪级别的消息隐藏,这就是为什么我一开始没有找到它的原因。消息如下所示:

14:29:00,260 TRACE clientInboundChannel-16 user.UserDestinationMessageHandler:175 - No user destinations found for /user/RtAuthorizedUser(super=AuthorizedUser(username=SIEM-User 1, authenticated=true, lastAnsweredHeartbeat=9971f9ea-8e64-4c24-823b-f7e6e277c775, alive=true), rtSessionId=RT_SID_iMonitor.443=782acc747aac01b9e0a7ece3ab2d27bd)/queue/overview/reqinfo/events
我建议开发人员至少将此消息设置为调试级别(甚至警告或错误),因为在发送过程中搜索问题时很难发现此信息。事实上,这是一个错误

从上述三种方法中删除heartbeat ID后,系统运行良好,不再丢失消息。因此,从一开始我就犯了一个错误,但我认为在这里使用
toString()
并不是最佳选择。现在Spring可以正确地翻译消息,生成这些消息(这些消息是调试级别的,而不是上面提到的跟踪):


在对我的应用程序,尤其是处理它的Spring代码进行了大量调试之后,我找到了这种行为的原因

问题既不是控制器,也不是Spring内部进程,而是我在Spring安全身份验证期间用于主体对象的类。它存储用户成功应答的最后一个心跳ID,以检查向系统发送消息的用户是否处于活动状态或会话是否已被视为已死亡。该ID包含在该对象的
equals()
hashCode()
toString()
方法中

Spring使用其中一种方法(经过一些测试,我猜它是
toString()
,在我看来这不是一个好的选择)来翻译
@SendToUser
操作的目标路径。如果字符串发生变化(当响应新的心跳ID时,我的应用程序就是这样),Spring将无法转换目标路径,并且不会发送消息。说明这一点的日志条目作为跟踪级别的消息隐藏,这就是为什么我一开始没有找到它的原因。消息如下所示:

14:29:00,260 TRACE clientInboundChannel-16 user.UserDestinationMessageHandler:175 - No user destinations found for /user/RtAuthorizedUser(super=AuthorizedUser(username=SIEM-User 1, authenticated=true, lastAnsweredHeartbeat=9971f9ea-8e64-4c24-823b-f7e6e277c775, alive=true), rtSessionId=RT_SID_iMonitor.443=782acc747aac01b9e0a7ece3ab2d27bd)/queue/overview/reqinfo/events
我建议开发人员至少将此消息设置为调试级别(甚至警告或错误),因为