@Test public void messageArrayFrameEmpty() { SockJsFrame frame = new SockJsFrame("a"); assertEquals("a[]", frame.getContent()); assertEquals(SockJsFrameType.MESSAGE, frame.getType()); assertEquals("[]", frame.getFrameData()); frame = new SockJsFrame("a[]"); assertEquals("a[]", frame.getContent()); assertEquals(SockJsFrameType.MESSAGE, frame.getType()); assertEquals("[]", frame.getFrameData()); }
@Test public void closeFrame() { SockJsFrame frame = SockJsFrame.closeFrame(3000, "Go Away!"); assertEquals("c[3000,\"Go Away!\"]", frame.getContent()); assertEquals(SockJsFrameType.CLOSE, frame.getType()); assertEquals("[3000,\"Go Away!\"]", frame.getFrameData()); }
logger.debug("Connection already closed (but not removed yet) for " + sockJsSession); SockJsFrame frame = SockJsFrame.closeFrameGoAway(); try { response.getBody().write(frame.getContentBytes()); logger.debug("Another " + getTransportType() + " connection still open for " + sockJsSession); String formattedFrame = getFrameFormat(request).format(SockJsFrame.closeFrameAnotherConnectionOpen()); try { response.getBody().write(formattedFrame.getBytes(SockJsFrame.CHARSET));
/** * Return data contained in a SockJS "message" and "close" frames. Otherwise * for SockJS "open" and "close" frames, which do not contain data, return * {@code null}. */ @Nullable public String getFrameData() { if (getType() == SockJsFrameType.OPEN || getType() == SockJsFrameType.HEARTBEAT) { return null; } else { return getContent().substring(1); } }
public void handleFrame(String payload) { SockJsFrame frame = new SockJsFrame(payload); switch (frame.getType()) { case OPEN: handleOpenFrame(); break; case HEARTBEAT: if (logger.isTraceEnabled()) { logger.trace("Received heartbeat in " + this); } break; case MESSAGE: handleMessageFrame(frame); break; case CLOSE: handleCloseFrame(frame); } }
public void initializeDelegateSession(WebSocketSession session) { synchronized (this.initSessionLock) { this.webSocketSession = session; try { // Let "our" handler know before sending the open frame to the remote handler delegateConnectionEstablished(); this.webSocketSession.sendMessage(new TextMessage(SockJsFrame.openFrame().getContent())); // Flush any messages cached in the mean time while (!this.initSessionCache.isEmpty()) { writeFrame(SockJsFrame.messageFrame(getMessageCodec(), this.initSessionCache.poll())); } scheduleHeartbeat(); this.openFrameSent = true; } catch (Throwable ex) { tryCloseWithSockJsTransportError(ex, CloseStatus.SERVER_ERROR); } } }
@Test public void handleFrameOpenWhenStatusNotNew() throws Exception { this.session.handleFrame(SockJsFrame.openFrame().getContent()); assertThat(this.session.isOpen(), is(true)); this.session.handleFrame(SockJsFrame.openFrame().getContent()); assertThat(this.session.disconnectStatus, equalTo(new CloseStatus(1006, "Server lost session"))); }
@Test public void heartbeatFrame() { SockJsFrame frame = SockJsFrame.heartbeatFrame(); assertEquals("h", frame.getContent()); assertEquals(SockJsFrameType.HEARTBEAT, frame.getType()); assertNull(frame.getFrameData()); }
@Test public void openFrame() { SockJsFrame frame = SockJsFrame.openFrame(); assertEquals("o", frame.getContent()); assertEquals(SockJsFrameType.OPEN, frame.getType()); assertNull(frame.getFrameData()); }
@Test public void messageArrayFrame() { SockJsFrame frame = SockJsFrame.messageFrame(new Jackson2SockJsMessageCodec(), "m1", "m2"); assertEquals("a[\"m1\",\"m2\"]", frame.getContent()); assertEquals(SockJsFrameType.MESSAGE, frame.getType()); assertEquals("[\"m1\",\"m2\"]", frame.getFrameData()); }
@Test public void handleFrameClose() throws Exception { this.session.handleFrame(SockJsFrame.openFrame().getContent()); this.session.handleFrame(SockJsFrame.closeFrame(1007, "").getContent()); assertThat(this.session.isOpen(), equalTo(false)); assertThat(this.session.disconnectStatus, equalTo(new CloseStatus(1007, ""))); verify(this.handler).afterConnectionEstablished(this.session); verifyNoMoreInteractions(this.handler); }
String frameData = frame.getFrameData(); if (frameData != null) { try { logger.trace("Processing SockJS message frame " + frame.getContent() + " in " + this);
@Override protected void flushCache() throws SockJsTransportFailureException { while (!getMessageCache().isEmpty()) { String message = getMessageCache().poll(); SockJsMessageCodec messageCodec = getSockJsServiceConfig().getMessageCodec(); SockJsFrame frame = SockJsFrame.messageFrame(messageCodec, message); writeFrame(frame); this.byteCount += (frame.getContentBytes().length + 1); if (logger.isTraceEnabled()) { logger.trace(this.byteCount + " bytes written so far, " + getMessageCache().size() + " more messages not flushed"); } if (this.byteCount >= getSockJsServiceConfig().getStreamBytesLimit()) { logger.trace("Streamed bytes limit reached, recycling current request"); resetRequest(); this.byteCount = 0; break; } } scheduleHeartbeat(); }
try { if (isClosed()) { response.getBody().write(SockJsFrame.closeFrameGoAway().getContentBytes()); return;
@Override protected void handleRequestInternal(ServerHttpRequest request, ServerHttpResponse response, boolean initialRequest) throws IOException { if (initialRequest) { writeFrame(SockJsFrame.openFrame()); } else if (!getMessageCache().isEmpty()) { flushCache(); } else { scheduleHeartbeat(); } }
@Override protected void flushCache() throws SockJsTransportFailureException { String[] messages = new String[getMessageCache().size()]; for (int i = 0; i < messages.length; i++) { messages[i] = getMessageCache().poll(); } SockJsMessageCodec messageCodec = getSockJsServiceConfig().getMessageCodec(); SockJsFrame frame = SockJsFrame.messageFrame(messageCodec, messages); writeFrame(frame); }
@Override public String format(SockJsFrame frame) { return String.format(this.format, preProcessContent(frame.getContent())); }
public static SockJsFrame closeFrame(int code, @Nullable String reason) { return new SockJsFrame("c[" + code + ",\"" + (reason != null ? reason : "") + "\"]"); }
@Test public void connectReceiveAndCloseWithStompFrame() throws Exception { StompHeaderAccessor accessor = StompHeaderAccessor.create(StompCommand.SEND); accessor.setDestination("/destination"); MessageHeaders headers = accessor.getMessageHeaders(); Message<byte[]> message = MessageBuilder.createMessage("body".getBytes(StandardCharsets.UTF_8), headers); byte[] bytes = new StompEncoder().encode(message); TextMessage textMessage = new TextMessage(bytes); SockJsFrame frame = SockJsFrame.messageFrame(new Jackson2SockJsMessageCodec(), textMessage.getPayload()); String body = "o\n" + frame.getContent() + "\n" + "c[3000,\"Go away!\"]"; ClientHttpResponse response = response(HttpStatus.OK, body); connect(response); verify(this.webSocketHandler).afterConnectionEstablished(any()); verify(this.webSocketHandler).handleMessage(any(), eq(textMessage)); verify(this.webSocketHandler).afterConnectionClosed(any(), eq(new CloseStatus(3000, "Go away!"))); verifyNoMoreInteractions(this.webSocketHandler); }
protected void sendHeartbeat() throws SockJsTransportFailureException { synchronized (this.responseLock) { if (isActive() && !this.heartbeatDisabled) { writeFrame(SockJsFrame.heartbeatFrame()); scheduleHeartbeat(); } } }