阻止消息等待10000 for BLOCKING..using spring websockets

时间:2016-03-30 10:14:37

标签: websocket spring-websocket asynchttpclient java-websocket

使用弹簧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]

很抱歉,如果问题的上述框架不明确。春季支持发送异常消息,如正常的javax websocket会发生Session.getAsyncRemote()。sendText(String text)

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

1 个答案:

答案 0 :(得分:1)

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

似乎与此非常相似:

WebSocket async send can result in blocked send once queue filled

我不是 必然 必须使用上述帖子中描述的期货或机制。 我真正得到的是:为什么要对servlet进行异步调用?有几个可以在同一个RemoteEndPoint上发送消息。 但是,您是否可以简单地对相关类进行同步调用,并保持在数据库中找到记录时使用的相同请求 - 响应流? :)

<强>更新

由于您在评论中添加了您需要关注速度的事实,并且由于您当前的解决方案似乎不适用,因此我们可以从不同的角度来看待问题。

我不是一个websocket专家,但据我所知,你试图用asynch servlet调用实现的是不可能的。 但是,如果更改项目的设计/配置,则应该可以实现。

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

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

@Autowired
SimpMessagingTemplate smt;

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

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

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

通过这样做,您可以减少延迟(调用servlet添加很多),并拥有可靠的技术。 您可以自行决定轻松快速地向一个用户或多个用户发送数千封邮件,而不会绊倒&#34; 10000 for BLOCKING&#34;问题,可能来自超过1个servlet&#34;回答相同的问题&#34; ;)

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

我建议查看这个有更多信息的文档: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html

以及我在SO上创建的以下帖子我在哪里使用它(我在帖子中遇到了另一个问题,与spring配置和上下文层次结构相关,但至少你有一些模板代码可供查看,代码正在运行):

Spring Websocket : receiving nothing from SimpMessagingTemplate

Spring : how to expose SimpMessagingTemplate bean to root context ?