Search in sources :

Example 1 with PongMessage

use of javax.websocket.PongMessage in project tomcat by apache.

the class WsFrameBase method processDataControl.

private boolean processDataControl() throws IOException {
    TransformationResult tr = transformation.getMoreData(opCode, fin, rsv, controlBufferBinary);
    if (TransformationResult.UNDERFLOW.equals(tr)) {
        return false;
    }
    // Control messages have fixed message size so
    // TransformationResult.OVERFLOW is not possible here
    controlBufferBinary.flip();
    if (opCode == Constants.OPCODE_CLOSE) {
        open = false;
        String reason = null;
        int code = CloseCodes.NORMAL_CLOSURE.getCode();
        if (controlBufferBinary.remaining() == 1) {
            controlBufferBinary.clear();
            // Payload must be zero or 2+ bytes long
            throw new WsIOException(new CloseReason(CloseCodes.PROTOCOL_ERROR, sm.getString("wsFrame.oneByteCloseCode")));
        }
        if (controlBufferBinary.remaining() > 1) {
            code = controlBufferBinary.getShort();
            if (controlBufferBinary.remaining() > 0) {
                CoderResult cr = utf8DecoderControl.decode(controlBufferBinary, controlBufferText, true);
                if (cr.isError()) {
                    controlBufferBinary.clear();
                    controlBufferText.clear();
                    throw new WsIOException(new CloseReason(CloseCodes.PROTOCOL_ERROR, sm.getString("wsFrame.invalidUtf8Close")));
                }
                // There will be no overflow as the output buffer is big
                // enough. There will be no underflow as all the data is
                // passed to the decoder in a single call.
                controlBufferText.flip();
                reason = controlBufferText.toString();
            }
        }
        wsSession.onClose(new CloseReason(Util.getCloseCode(code), reason));
    } else if (opCode == Constants.OPCODE_PING) {
        if (wsSession.isOpen()) {
            wsSession.getBasicRemote().sendPong(controlBufferBinary);
        }
    } else if (opCode == Constants.OPCODE_PONG) {
        MessageHandler.Whole<PongMessage> mhPong = wsSession.getPongMessageHandler();
        if (mhPong != null) {
            try {
                mhPong.onMessage(new WsPongMessage(controlBufferBinary));
            } catch (Throwable t) {
                handleThrowableOnSend(t);
            } finally {
                controlBufferBinary.clear();
            }
        }
    } else {
        // Should have caught this earlier but just in case...
        controlBufferBinary.clear();
        throw new WsIOException(new CloseReason(CloseCodes.PROTOCOL_ERROR, sm.getString("wsFrame.invalidOpCode", Integer.valueOf(opCode))));
    }
    controlBufferBinary.clear();
    newFrame();
    return true;
}
Also used : MessageHandler(javax.websocket.MessageHandler) CloseReason(javax.websocket.CloseReason) PongMessage(javax.websocket.PongMessage) CoderResult(java.nio.charset.CoderResult)

Example 2 with PongMessage

use of javax.websocket.PongMessage in project spring-framework by spring-projects.

the class StandardWebSocketHandlerAdapter method toMessage.

private <T> WebSocketMessage toMessage(T message) {
    WebSocketSession session = this.delegateSession;
    Assert.state(session != null, "Cannot create message without a session");
    if (message instanceof String) {
        byte[] bytes = ((String) message).getBytes(StandardCharsets.UTF_8);
        return new WebSocketMessage(Type.TEXT, session.bufferFactory().wrap(bytes));
    } else if (message instanceof ByteBuffer) {
        DataBuffer buffer = session.bufferFactory().wrap((ByteBuffer) message);
        return new WebSocketMessage(Type.BINARY, buffer);
    } else if (message instanceof PongMessage) {
        DataBuffer buffer = session.bufferFactory().wrap(((PongMessage) message).getApplicationData());
        return new WebSocketMessage(Type.PONG, buffer);
    } else {
        throw new IllegalArgumentException("Unexpected message type: " + message);
    }
}
Also used : WebSocketMessage(org.springframework.web.reactive.socket.WebSocketMessage) PongMessage(javax.websocket.PongMessage) ByteBuffer(java.nio.ByteBuffer) WebSocketSession(org.springframework.web.reactive.socket.WebSocketSession) DataBuffer(org.springframework.core.io.buffer.DataBuffer)

Example 3 with PongMessage

use of javax.websocket.PongMessage in project jetty.project by eclipse.

the class JsrEndpointEventDriver method onPongMessage.

private void onPongMessage(ByteBuffer buffer) {
    final MessageHandlerWrapper wrapper = jsrsession.getMessageHandlerWrapper(MessageType.PONG);
    if (wrapper == null) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("No PONG MessageHandler declared");
        }
        return;
    }
    ByteBuffer pongBuf = null;
    if (BufferUtil.isEmpty(buffer)) {
        pongBuf = BufferUtil.EMPTY_BUFFER;
    } else {
        pongBuf = ByteBuffer.allocate(buffer.remaining());
        BufferUtil.put(buffer, pongBuf);
        BufferUtil.flipToFlush(pongBuf, 0);
    }
    @SuppressWarnings("unchecked") Whole<PongMessage> pongHandler = (Whole<PongMessage>) wrapper.getHandler();
    pongHandler.onMessage(new JsrPongMessage(pongBuf));
}
Also used : MessageHandlerWrapper(org.eclipse.jetty.websocket.jsr356.MessageHandlerWrapper) PongMessage(javax.websocket.PongMessage) JsrPongMessage(org.eclipse.jetty.websocket.jsr356.JsrPongMessage) ByteBuffer(java.nio.ByteBuffer) Whole(javax.websocket.MessageHandler.Whole) JsrPongMessage(org.eclipse.jetty.websocket.jsr356.JsrPongMessage)

Example 4 with PongMessage

use of javax.websocket.PongMessage in project undertow by undertow-io.

the class AnnotatedEndpointFactory method create.

public static AnnotatedEndpointFactory create(final Class<?> endpointClass, final EncodingFactory encodingFactory, final Set<String> paths) throws DeploymentException {
    final Set<Class<? extends Annotation>> found = new HashSet<>();
    BoundMethod onOpen = null;
    BoundMethod onClose = null;
    BoundMethod onError = null;
    BoundMethod textMessage = null;
    BoundMethod binaryMessage = null;
    BoundMethod pongMessage = null;
    Class<?> c = endpointClass;
    do {
        for (final Method method : c.getDeclaredMethods()) {
            if (method.isAnnotationPresent(OnOpen.class)) {
                if (found.contains(OnOpen.class)) {
                    if (!onOpen.overrides(method)) {
                        throw JsrWebSocketMessages.MESSAGES.moreThanOneAnnotation(OnOpen.class);
                    } else {
                        continue;
                    }
                }
                found.add(OnOpen.class);
                onOpen = new BoundMethod(method, null, false, 0, new BoundSingleParameter(method, Session.class, true), new BoundSingleParameter(method, EndpointConfig.class, true), createBoundPathParameters(method, paths, endpointClass));
            }
            if (method.isAnnotationPresent(OnClose.class)) {
                if (found.contains(OnClose.class)) {
                    if (!onClose.overrides(method)) {
                        throw JsrWebSocketMessages.MESSAGES.moreThanOneAnnotation(OnClose.class);
                    } else {
                        continue;
                    }
                }
                found.add(OnClose.class);
                onClose = new BoundMethod(method, null, false, 0, new BoundSingleParameter(method, Session.class, true), new BoundSingleParameter(method, CloseReason.class, true), createBoundPathParameters(method, paths, endpointClass));
            }
            if (method.isAnnotationPresent(OnError.class)) {
                if (found.contains(OnError.class)) {
                    if (!onError.overrides(method)) {
                        throw JsrWebSocketMessages.MESSAGES.moreThanOneAnnotation(OnError.class);
                    } else {
                        continue;
                    }
                }
                found.add(OnError.class);
                onError = new BoundMethod(method, null, false, 0, new BoundSingleParameter(method, Session.class, true), new BoundSingleParameter(method, Throwable.class, false), createBoundPathParameters(method, paths, endpointClass));
            }
            if (method.isAnnotationPresent(OnMessage.class) && !method.isBridge()) {
                if (binaryMessage != null && binaryMessage.overrides(method)) {
                    continue;
                }
                if (textMessage != null && textMessage.overrides(method)) {
                    continue;
                }
                if (pongMessage != null && pongMessage.overrides(method)) {
                    continue;
                }
                long maxMessageSize = method.getAnnotation(OnMessage.class).maxMessageSize();
                boolean messageHandled = false;
                //this is a bit more complex
                Class<?>[] parameterTypes = method.getParameterTypes();
                int booleanLocation = -1;
                for (int i = 0; i < parameterTypes.length; ++i) {
                    if (hasAnnotation(PathParam.class, method.getParameterAnnotations()[i])) {
                        continue;
                    }
                    final Class<?> param = parameterTypes[i];
                    if (param == boolean.class || param == Boolean.class) {
                        booleanLocation = i;
                    } else if (encodingFactory.canDecodeText(param)) {
                        if (textMessage != null) {
                            throw JsrWebSocketMessages.MESSAGES.moreThanOneAnnotation(OnMessage.class);
                        }
                        textMessage = new BoundMethod(method, param, true, maxMessageSize, new BoundSingleParameter(method, Session.class, true), new BoundSingleParameter(method, boolean.class, true), new BoundSingleParameter(i, param), createBoundPathParameters(method, paths, endpointClass));
                        messageHandled = true;
                        break;
                    } else if (encodingFactory.canDecodeBinary(param)) {
                        if (binaryMessage != null) {
                            throw JsrWebSocketMessages.MESSAGES.moreThanOneAnnotation(OnMessage.class);
                        }
                        binaryMessage = new BoundMethod(method, param, true, maxMessageSize, new BoundSingleParameter(method, Session.class, true), new BoundSingleParameter(method, boolean.class, true), new BoundSingleParameter(i, param), createBoundPathParameters(method, paths, endpointClass));
                        messageHandled = true;
                        break;
                    } else if (param.equals(byte[].class)) {
                        if (binaryMessage != null) {
                            throw JsrWebSocketMessages.MESSAGES.moreThanOneAnnotation(OnMessage.class);
                        }
                        binaryMessage = new BoundMethod(method, byte[].class, false, maxMessageSize, new BoundSingleParameter(method, Session.class, true), new BoundSingleParameter(method, boolean.class, true), new BoundSingleParameter(i, byte[].class), createBoundPathParameters(method, paths, endpointClass));
                        messageHandled = true;
                        break;
                    } else if (param.equals(ByteBuffer.class)) {
                        if (binaryMessage != null) {
                            throw JsrWebSocketMessages.MESSAGES.moreThanOneAnnotation(OnMessage.class);
                        }
                        binaryMessage = new BoundMethod(method, ByteBuffer.class, false, maxMessageSize, new BoundSingleParameter(method, Session.class, true), new BoundSingleParameter(method, boolean.class, true), new BoundSingleParameter(i, ByteBuffer.class), createBoundPathParameters(method, paths, endpointClass));
                        messageHandled = true;
                        break;
                    } else if (param.equals(InputStream.class)) {
                        if (binaryMessage != null) {
                            throw JsrWebSocketMessages.MESSAGES.moreThanOneAnnotation(OnMessage.class);
                        }
                        binaryMessage = new BoundMethod(method, InputStream.class, false, maxMessageSize, new BoundSingleParameter(method, Session.class, true), new BoundSingleParameter(method, boolean.class, true), new BoundSingleParameter(i, InputStream.class), createBoundPathParameters(method, paths, endpointClass));
                        messageHandled = true;
                        break;
                    } else if (param.equals(String.class) && getPathParam(method, i) == null) {
                        if (textMessage != null) {
                            throw JsrWebSocketMessages.MESSAGES.moreThanOneAnnotation(OnMessage.class);
                        }
                        textMessage = new BoundMethod(method, String.class, false, maxMessageSize, new BoundSingleParameter(method, Session.class, true), new BoundSingleParameter(method, boolean.class, true), new BoundSingleParameter(i, String.class), createBoundPathParameters(method, paths, endpointClass));
                        messageHandled = true;
                        break;
                    } else if (param.equals(Reader.class) && getPathParam(method, i) == null) {
                        if (textMessage != null) {
                            throw JsrWebSocketMessages.MESSAGES.moreThanOneAnnotation(OnMessage.class);
                        }
                        textMessage = new BoundMethod(method, Reader.class, false, maxMessageSize, new BoundSingleParameter(method, Session.class, true), new BoundSingleParameter(method, boolean.class, true), new BoundSingleParameter(i, Reader.class), createBoundPathParameters(method, paths, endpointClass));
                        messageHandled = true;
                        break;
                    } else if (param.equals(PongMessage.class)) {
                        if (pongMessage != null) {
                            throw JsrWebSocketMessages.MESSAGES.moreThanOneAnnotation(OnMessage.class);
                        }
                        pongMessage = new BoundMethod(method, PongMessage.class, false, maxMessageSize, new BoundSingleParameter(method, Session.class, true), new BoundSingleParameter(i, PongMessage.class), createBoundPathParameters(method, paths, endpointClass));
                        messageHandled = true;
                        break;
                    }
                }
                if (!messageHandled && booleanLocation != -1) {
                    //so it turns out that the boolean was the message type and not a final fragement indicator
                    if (textMessage != null) {
                        throw JsrWebSocketMessages.MESSAGES.moreThanOneAnnotation(OnMessage.class);
                    }
                    Class<?> boolClass = parameterTypes[booleanLocation];
                    textMessage = new BoundMethod(method, boolClass, true, maxMessageSize, new BoundSingleParameter(method, Session.class, true), new BoundSingleParameter(method, boolean.class, true), new BoundSingleParameter(booleanLocation, boolClass), createBoundPathParameters(method, paths, endpointClass));
                    messageHandled = true;
                }
                if (!messageHandled) {
                    throw JsrWebSocketMessages.MESSAGES.couldNotFindMessageParameter(method);
                }
            }
        }
        c = c.getSuperclass();
    } while (c != Object.class && c != null);
    return new AnnotatedEndpointFactory(endpointClass, onOpen, onClose, onError, textMessage, binaryMessage, pongMessage);
}
Also used : InputStream(java.io.InputStream) Reader(java.io.Reader) Method(java.lang.reflect.Method) OnMessage(javax.websocket.OnMessage) ByteBuffer(java.nio.ByteBuffer) Annotation(java.lang.annotation.Annotation) PongMessage(javax.websocket.PongMessage) HashSet(java.util.HashSet) Session(javax.websocket.Session)

Example 5 with PongMessage

use of javax.websocket.PongMessage in project undertow by undertow-io.

the class FrameHandler method onFullPongMessage.

@Override
protected void onFullPongMessage(final WebSocketChannel webSocketChannel, BufferedBinaryMessage bufferedBinaryMessage) {
    if (session.isSessionClosed()) {
        //to bad, the channel has already been closed
        //we just ignore messages that are received after we have closed, as the endpoint is no longer in a valid state to deal with them
        //this this should only happen if a message was on the wire when we called close()
        bufferedBinaryMessage.getData().free();
        return;
    }
    final HandlerWrapper handler = getHandler(FrameType.PONG);
    if (handler != null) {
        final Pooled<ByteBuffer[]> pooled = bufferedBinaryMessage.getData();
        final PongMessage message = DefaultPongMessage.create(toBuffer(pooled.getResource()));
        session.getContainer().invokeEndpointMethod(executor, new Runnable() {

            @Override
            public void run() {
                try {
                    ((MessageHandler.Whole) handler.getHandler()).onMessage(message);
                } catch (Exception e) {
                    invokeOnError(e);
                } finally {
                    pooled.close();
                }
            }
        });
    }
}
Also used : MessageHandler(javax.websocket.MessageHandler) PongMessage(javax.websocket.PongMessage) IOException(java.io.IOException)

Aggregations

PongMessage (javax.websocket.PongMessage)5 ByteBuffer (java.nio.ByteBuffer)3 MessageHandler (javax.websocket.MessageHandler)2 IOException (java.io.IOException)1 InputStream (java.io.InputStream)1 Reader (java.io.Reader)1 Annotation (java.lang.annotation.Annotation)1 Method (java.lang.reflect.Method)1 CoderResult (java.nio.charset.CoderResult)1 HashSet (java.util.HashSet)1 CloseReason (javax.websocket.CloseReason)1 Whole (javax.websocket.MessageHandler.Whole)1 OnMessage (javax.websocket.OnMessage)1 Session (javax.websocket.Session)1 JsrPongMessage (org.eclipse.jetty.websocket.jsr356.JsrPongMessage)1 MessageHandlerWrapper (org.eclipse.jetty.websocket.jsr356.MessageHandlerWrapper)1 DataBuffer (org.springframework.core.io.buffer.DataBuffer)1 WebSocketMessage (org.springframework.web.reactive.socket.WebSocketMessage)1 WebSocketSession (org.springframework.web.reactive.socket.WebSocketSession)1