private void sendBlockingMessage(ConcurrentWebSocketSessionDecorator session) throws InterruptedException { Executors.newSingleThreadExecutor().submit(() -> { TextMessage message = new TextMessage("slow message"); try { session.sendMessage(message); } catch (IOException e) { e.printStackTrace(); } }); BlockingSession delegate = (BlockingSession) session.getDelegate(); assertTrue(delegate.getSentMessageLatch().await(5, TimeUnit.SECONDS)); }
@Test public void closeStatusChangesToSessionNotReliable() throws Exception { BlockingSession session = new BlockingSession(); session.setId("123"); session.setOpen(true); CountDownLatch sentMessageLatch = session.getSentMessageLatch(); int sendTimeLimit = 100; int bufferSizeLimit = 1024; final ConcurrentWebSocketSessionDecorator decorator = new ConcurrentWebSocketSessionDecorator(session, sendTimeLimit, bufferSizeLimit); Executors.newSingleThreadExecutor().submit((Runnable) () -> { TextMessage message = new TextMessage("slow message"); try { decorator.sendMessage(message); } catch (IOException e) { e.printStackTrace(); } }); assertTrue(sentMessageLatch.await(5, TimeUnit.SECONDS)); // ensure some send time elapses Thread.sleep(sendTimeLimit + 100); decorator.close(CloseStatus.PROTOCOL_ERROR); assertEquals("CloseStatus should have changed to SESSION_NOT_RELIABLE", CloseStatus.SESSION_NOT_RELIABLE, session.getCloseStatus()); }
@Test // SPR-17140 public void overflowStrategyDrop() throws IOException, InterruptedException { BlockingSession session = new BlockingSession(); session.setId("123"); session.setOpen(true); final ConcurrentWebSocketSessionDecorator decorator = new ConcurrentWebSocketSessionDecorator(session, 10*1000, 1024, OverflowStrategy.DROP); sendBlockingMessage(decorator); StringBuilder sb = new StringBuilder(); for (int i = 0 ; i < 1023; i++) { sb.append("a"); } for (int i=0; i < 5; i++) { TextMessage message = new TextMessage(sb.toString()); decorator.sendMessage(message); } assertEquals(1023, decorator.getBufferSize()); assertTrue(session.isOpen()); }
@Test public void sendBufferSizeExceeded() throws IOException, InterruptedException { BlockingSession session = new BlockingSession(); session.setId("123"); session.setOpen(true); final ConcurrentWebSocketSessionDecorator decorator = new ConcurrentWebSocketSessionDecorator(session, 10*1000, 1024); sendBlockingMessage(decorator); StringBuilder sb = new StringBuilder(); for (int i = 0 ; i < 1023; i++) { sb.append("a"); } TextMessage message = new TextMessage(sb.toString()); decorator.sendMessage(message); assertEquals(1023, decorator.getBufferSize()); assertTrue(session.isOpen()); try { decorator.sendMessage(message); fail("Expected exception"); } catch (SessionLimitExceededException ex) { String actual = ex.getMessage(); String regex = "Buffer size [\\d]+ bytes for session '123' exceeds the allowed limit 1024"; assertTrue("Unexpected message: " + actual, actual.matches(regex)); assertEquals(CloseStatus.SESSION_NOT_RELIABLE, ex.getStatus()); } }
@Test public void send() throws IOException { TestWebSocketSession session = new TestWebSocketSession(); session.setOpen(true); ConcurrentWebSocketSessionDecorator decorator = new ConcurrentWebSocketSessionDecorator(session, 1000, 1024); TextMessage textMessage = new TextMessage("payload"); decorator.sendMessage(textMessage); assertEquals(1, session.getSentMessages().size()); assertEquals(textMessage, session.getSentMessages().get(0)); assertEquals(0, decorator.getBufferSize()); assertEquals(0, decorator.getTimeSinceSendStarted()); assertTrue(session.isOpen()); }
@Test public void sendTimeLimitExceeded() throws IOException, InterruptedException { BlockingSession session = new BlockingSession(); session.setId("123"); session.setOpen(true); final ConcurrentWebSocketSessionDecorator decorator = new ConcurrentWebSocketSessionDecorator(session, 100, 1024); sendBlockingMessage(decorator); // Exceed send time.. Thread.sleep(200); try { TextMessage payload = new TextMessage("payload"); decorator.sendMessage(payload); fail("Expected exception"); } catch (SessionLimitExceededException ex) { String actual = ex.getMessage(); String regex = "Send time [\\d]+ \\(ms\\) for session '123' exceeded the allowed limit 100"; assertTrue("Unexpected message: " + actual, actual.matches(regex)); assertEquals(CloseStatus.SESSION_NOT_RELIABLE, ex.getStatus()); } }
@Test public void sendAfterBlockedSend() throws IOException, InterruptedException { BlockingSession session = new BlockingSession(); session.setOpen(true); final ConcurrentWebSocketSessionDecorator decorator = new ConcurrentWebSocketSessionDecorator(session, 10 * 1000, 1024); sendBlockingMessage(decorator); Thread.sleep(50); assertTrue(decorator.getTimeSinceSendStarted() > 0); TextMessage payload = new TextMessage("payload"); for (int i = 0; i < 5; i++) { decorator.sendMessage(payload); } assertTrue(decorator.getTimeSinceSendStarted() > 0); assertEquals(5 * payload.getPayloadLength(), decorator.getBufferSize()); assertTrue(session.isOpen()); }
public boolean sendToUser(String username, TextMessage msg) { try { ConcurrentWebSocketSessionDecorator session = sessionMap.get(username); if (session == null || !session.isOpen()) { return false; } session.sendMessage(msg); return true; } catch (Exception e) { log.error("send to user error, username:[{}]", username, e); return false; } } }
@Override public void afterConnectionEstablished(WebSocketSession session) throws IOException { String username = (String) session.getAttributes().get("username"); ConcurrentWebSocketSessionDecorator sessionDecorator = new ConcurrentWebSocketSessionDecorator(session, 1000, 5120); sessionMap.put(username, sessionDecorator); log.info("connect succ, username:[{}]", username); JSONObject jsonObject = new JSONObject(); jsonObject.put("action", "connect"); jsonObject.put("username", username); sessionDecorator.sendMessage(new TextMessage(jsonObject.toJSONString())); }
public void sendAllUser(String msg) { String username = StringUtils.EMPTY; try { for (Map.Entry<String, ConcurrentWebSocketSessionDecorator> entry : sessionMap.entrySet()) { username = entry.getKey(); ConcurrentWebSocketSessionDecorator session = entry.getValue(); if (!session.isOpen()) { log.info("session close when send all user, username:[{}]", username); continue; } session.sendMessage(new TextMessage(msg)); } } catch (Exception e) { log.error("send all user error, username:[{}]", username, e); } }
public boolean safeSend(WebSocketSession session, WebSocketMessage webSocketMessage) { if (!session.isOpen()) { return false; } try { ConcurrentWebSocketSessionDecorator decorator = sessionDecoratorMap.computeIfAbsent(session.getId(), k -> new ConcurrentWebSocketSessionDecorator( session, getSendTimeLimit(), getBufferSizeLimit())); decorator.sendMessage(webSocketMessage); return true; } catch (Exception e) { sessionDecoratorMap.remove(session.getId()); logger.error("safeSend error:{}", e.getMessage()); return false; } } }
private Future<ResponseObject> callRpcAsyncInternal(RequestObject requestObject, boolean ignoreResponse) throws IOException { if (requestObject == null || requestObject.getId() == null) { throw new RuntimeException("callRpcAsyncInternal failure requestObject is null or requestObject's id is null"); } RpcResponseFuture rpcResponseFuture = null; if (!ignoreResponse) { rpcResponseFuture = new RpcResponseFuture(); rpcCallback.put(requestObject.getId(), rpcResponseFuture); } ConcurrentWebSocketSessionDecorator decorator = sessionDecoratorMap.computeIfAbsent(webSocketSession.getId(), k -> new ConcurrentWebSocketSessionDecorator( webSocketSession, getSendTimeLimit(), getBufferSizeLimit())); decorator.sendMessage(new TextMessage(JSON.toJSONString(requestObject))); return rpcResponseFuture; }
public void listenSub(String channel, Boolean subscribe, List params, ChannelMessageHandler handler) throws IOException { if (!isOpen()) { throw new RuntimeException("callRpcAsyncInternal failure webSocketSession is not open"); } if (subscribe != null && subscribe) { channelCallback.put(channel, handler); } else { channelCallback.remove(channel); } SubRequestObject subRequestObject = new SubRequestObject(); subRequestObject.setChannel(channel); subRequestObject.setSubscribe(subscribe); subRequestObject.setParams(params); ConcurrentWebSocketSessionDecorator decorator = sessionDecoratorMap.computeIfAbsent(webSocketSession.getId(), k -> new ConcurrentWebSocketSessionDecorator( webSocketSession, getSendTimeLimit(), getBufferSizeLimit())); decorator.sendMessage(new TextMessage(JSON.toJSONString(subRequestObject))); }