使用 spring websockets 阻塞消息待处理 10000

Blocking message pending 10000 for BLOCKING..using spring websockets

我在使用 spring websockets 时遇到以下错误:

用例:在我们的服务器端代码中,我们具有在数据库中搜索值的功能..如果数据库中不存在这些值..它将命中一个 servlet 并获取数据..第二部分即,命中servlet并获取数据是异步调用。

因此对于一个请求,我们必须在数据库中搜索多项内容..

示例:在请求中我们得到了一些参数通道:1 此频道映射到多个 ID,比如 1 映射到 1,2,3,4,5

在 websocket 中,一旦请求到达服务器,我将提取通道并获取所有 id 的映射和 运行 id 的循环如下:

for(int i=0;i<ids.length;i++)
{

SomeObject databaseRespObj=callToDatabase(i); //SomeObject contains two fields value exists and string values

if(!databaseRespObj.valuesExists)
{
AsynchronouscallToServelt(i); 
//once response received it will send message immediately using session
}

}

在执行上述服务器端代码时,有时只有我遇到以下错误。

java.lang.IllegalStateException: Blocking message pending 10000 for BLOCKING
        at org.eclipse.jetty.websocket.common.WebSocketRemoteEndpoint.lockMsg(WebSocketRemoteEndpoint.java:130) ~[websocket-common-9.3.8.v20160314.jar:9.3.8.v20160314]
        at org.eclipse.jetty.websocket.common.WebSocketRemoteEndpoint.sendString(WebSocketRemoteEndpoint.java:379) ~[websocket-common-9.3.8.v20160314.jar:9.3.8.v20160314]
        at org.springframework.web.socket.adapter.jetty.JettyWebSocketSession.sendTextMessage(JettyWebSocketSession.java:188) ~[spring-websocket-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at org.springframework.web.socket.adapter.AbstractWebSocketSession.sendMessage(AbstractWebSocketSession.java:105) ~[spring-websocket-4.2.4.RELEASE.jar:4.2.4.RELEASE]

抱歉,如果问题的上述框架不是 clear.Will spring 支持像普通 javax websocket 那样发送异步消息 Session.getAsyncRemote().sendText(String text)

在spring中使用websocket会话发送异步消息的配置是什么

据我了解,当异步技术启动时,您有多个线程在同一个 RemoteEndpoint 上发送消息。

似乎与此非常相似:

WebSocket async send can result in blocked send once queue filled

我不认为你 必须 必须使用上述 post 中描述的期货或机制。 我真正不明白的是:为什么对 servlet 进行异步调用?当然,几个人可以在同一个 RemoteEndPoint 上发送消息。 但是,您不能简单地对相关的 class 进行同步调用,并保持与在数据库中找到记录时所使用的相同的请求-响应流程吗? :)

更新

既然你在评论中添加了你需要关注速度的事实,而且你目前的解决方案似乎不适用,那么让我们换个角度看问题。

我不是 websocket 专家,但据我了解,您尝试通过异步 servlet 调用实现的目标是不可能的。 但是,如果您更改项目的 design/config,这应该是可以实现的。

我个人使用 Websockets 能够向 任意用户 发送消息 不一定发出请求 - 只要当他连接时,他必须得到消息。

为此,我只需使用 Spring 在其 websocket 支持中提供的 SimpMessagingTemplate class。要向任何我想要的用户发送消息,我会这样做:

@Autowired
SimpMessagingTemplate smt;

(.......)
smt.convertAndSendToUser(recipient.getUsername(), "/queue/notify", payload);

所以在你的情况下,你可以,在你的循环中

  • 进行 class 实例方法调用(而不是 servlet,没有网络传输,你不能更快!只需调用你的业务逻辑/服务/其他)
  • 每次方法 returns 数据,使用上面代码段中的 SimpMessagingTemplate :)
  • 如果你愿意,你仍然可以异步进行! :)

通过这样做,您可以减少延迟(调用 servlet 会增加很多),并且拥有可靠的技术。 您可以自行决定轻松快速地向一个用户或多个用户发送数千条消息,而不会遇到“10000 条阻塞”问题,该问题可能来自 1 个以上的 servlet "answering the same question" ;)

要从 Spring 获取 SimpMessagingTemplate,您需要使用 <websocket:message-broker> 标记或等效的非 xml-java-config。

我建议查看此文档,其中包含更多信息: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html

和以下 post 我在 SO 上创建的我正在使用它的地方(我在 post 中遇到了另一个问题,与 spring 配置和上下文层次结构有关,但是至少你有一些模板代码可以看,代码可以工作):