svs teja
svs teja

Reputation: 1017

Blocking message pending 10000 for BLOCKING..using spring websockets

I am facing the following error while using spring websockets:

Use case: On our server side code we have a fucntionality to search values in data base..if the values are not present in database..it will hit a servlet and get the data..The second part i.e., hitting servlet and getting the data is asynchronous call.

So for one request there are multiple things we have to search for in data base..

Example: In request we got a some parameter channel: 1 This channel is mapped to multiple ids say 1 is mapped to 1,2,3,4,5

In websocket once the request comes to server i will extract the channel and get all the id's mapped and run a loop over id's as follows:

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
}

}

While execution of above server side code,some times only i am facing the below error.

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]

Sorry if the above framing of the question is not clear.Will spring support sending asynchronous messages like normal javax websocket does Session.getAsyncRemote().sendText(String text)

What is the configuration made in spring to send asynchronous messages using websocket session

Upvotes: 3

Views: 7717

Answers (1)

niilzon
niilzon

Reputation: 426

From what I understand, you have multiple threads sending messages on the same RemoteEndpoint when the asynchronous technique kicks in.

Seems very similar to this :

WebSocket async send can result in blocked send once queue filled

I don't thing you necessarily have to use Futures or mechanisms described in the above post. What I don't really get is : why doing asynchronous call to servlets ? Ofcourse several could send messages on the same RemoteEndPoint.. But can't you simply make synchronous calls to the relevant classes and keep the same request-response flow that you use when records are found in your database ? :)

UPDATE

Since you added in comments the fact that you need to focus on speed, and since it seems that your current solution is not applicable, let's maybe have a look at the problem from a different angle.

I'm not a websocket expert but as far as I understand what you try to achieve with the asynch servlet calls is not possible. However, if you change the design/config of your project, this should be achievable.

Personally I use Websockets to be able to send a message to an arbitrary user that did not necessarily made a request - as long as he is connected, he must get the message.

To do this, I simply use the SimpMessagingTemplate class offered by Spring in their websocket support. To send a message to ANY USER THAT I WANT, I do this :

@Autowired
SimpMessagingTemplate smt;

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

So in your case, you could, in your loop :

  • make class instance method calls (instead of a servlet, no network transit, you cannot be faster ! Just a call to your biz-logic / service / whatever)
  • every time a method returns data, use the SimpMessagingTemplate like in the snippet here above :)
  • you can still do it asynchronously if you want ! :)

By doing this, you reduce latency (calling servlets adds alot), and have a reliable technique. You can easily and quickly send thousands of messages to one user or to several users, at your own discretion, without stumbling upon the "10000 for BLOCKING" problem, which probably comes from more than 1 servlet "answering the same question" ;)

To obtain a SimpMessagingTemplate from Spring, you will need to use the <websocket:message-broker> tag or the equivalent non-xml-java-config.

I suggest to check this doc which has more info : http://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html

and the following post I created on SO where I am using it (I've got another problem in the post, related to spring configuration and context hierarchies, but at least you have some template code to look at, the code is working) :

Spring Websocket : receiving nothing from SimpMessagingTemplate

Spring : how to expose SimpMessagingTemplate bean to root context ?

Upvotes: 1

Related Questions