Package org.apache.tomcat.websocket.server

## Class WsRemoteEndpointImplServer

- java.lang.Object
- - org.apache.tomcat.websocket.WsRemoteEndpointImplBase
  - - org.apache.tomcat.websocket.server.WsRemoteEndpointImplServer

- All Implemented Interfaces:
    `RemoteEndpoint`

      public class WsRemoteEndpointImplServer
      extends WsRemoteEndpointImplBase

  This is the server side `RemoteEndpoint` implementation - i.e. what the server uses to send data to the client.

- - ### Nested Class Summary

    - ### Nested classes/interfaces inherited from interface jakarta.websocket.RemoteEndpoint

      `RemoteEndpoint.Async, RemoteEndpoint.Basic`

  - ### Field Summary

    - ### Fields inherited from class org.apache.tomcat.websocket.WsRemoteEndpointImplBase

      `messagePartInProgress, SENDRESULT_OK`

  - ### Constructor Summary

    Constructors
    Constructor | Description
    --- | ---
    `WsRemoteEndpointImplServer​(SocketWrapperBase<?> socketWrapper, UpgradeInfo upgradeInfo, WsServerContainer serverContainer, WebConnection connection)` |

  - ### Method Summary

    All Methods Instance Methods Concrete Methods
    Modifier and Type | Method | Description
    --- | --- | ---
    `protected boolean` | `acquireMessagePartInProgressSemaphore​(byte opCode, long timeoutExpiry)` | Acquire the semaphore that allows a message part to be written.
    `protected void` | `doClose()` |
    `protected void` | `doWrite​(SendHandler handler, long blockingWriteTimeoutExpiry, ByteBuffer... buffers)` |
    `protected Lock` | `getLock()` |
    `protected long` | `getTimeoutExpiry()` |
    `protected boolean` | `isMasked()` |
    `protected void` | `onTimeout​(boolean useDispatch)` |
    `void` | `onWritePossible​(boolean useDispatch)` |
    `protected void` | `setTransformation​(Transformation transformation)` |
    `protected void` | `updateStats​(long payloadLength)` | Hook for updating server side statistics.

    - ### Methods inherited from class org.apache.tomcat.websocket.WsRemoteEndpointImplBase

      `close, flushBatch, getBatchingAllowed, getSendStream, getSendTimeout, getSendWriter, sendBytes, sendBytesByCompletion, sendBytesByFuture, sendObject, sendObjectByCompletion, sendObjectByFuture, sendPartialBytes, sendPartialString, sendPing, sendPong, sendString, sendStringByCompletion, sendStringByFuture, setBatchingAllowed, setEncoders, setSendTimeout, setSession`

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Constructor Detail

    - #### WsRemoteEndpointImplServer

          public WsRemoteEndpointImplServer​(SocketWrapperBase<?> socketWrapper,
                                            UpgradeInfo upgradeInfo,
                                            WsServerContainer serverContainer,
                                            WebConnection connection)

  - ### Method Detail

    - #### isMasked

          protected final boolean isMasked()

      Specified by:
        `isMasked` in class `WsRemoteEndpointImplBase`

    - #### acquireMessagePartInProgressSemaphore

          protected boolean acquireMessagePartInProgressSemaphore​(byte opCode,
                                                                  long timeoutExpiry)
                                                           throws InterruptedException

      Acquire the semaphore that allows a message part to be written.

      The close message is a special case. It needs to be blocking else implementing the clean-up that follows the sending of the close message gets a lot more complicated. On the server, this creates additional complications as a dead-lock may occur in the following scenario:

      1. Application thread writes message using non-blocking
      2. Write does not complete (write logic holds message pending lock)
      3. Socket is added to poller (or equivalent) for write
      4. Client sends close message
      5. Container processes received close message and tries to send close message in response
      6. Container holds socket lock and is blocked waiting for message pending lock
      7. Poller fires write possible event for socket
      8. Container tries to process write possible event but is blocked waiting for socket lock
      9. Processing of the WebSocket connection is dead-locked until the original message write times out
      The purpose of this method is to break the above dead-lock. It does this by returning control of the processor to the socket wrapper and releasing the socket lock while waiting for the pending message write to complete. Normally, that would be a terrible idea as it creates the possibility that the processor is returned to the pool more than once under various error conditions. In this instance it is safe because these are upgrade processors (isUpgrade() returns `true`) and upgrade processors are never pooled.

      TODO: Despite the complications it creates, it would be worth exploring the possibility of processing a received close frame in a non-blocking manner.

      Overrides:
        `acquireMessagePartInProgressSemaphore` in class `WsRemoteEndpointImplBase`
      Parameters:
        `opCode` - The OPCODE for the message to be written
        `timeoutExpiry` - The time when the attempt to acquire the semaphore should expire
      Returns:
        `true` if the semaphore is obtained, otherwise `false`.
      Throws:
        `InterruptedException` - If the wait for the semaphore is interrupted

    - #### doWrite

          protected void doWrite​(SendHandler handler,
                                 long blockingWriteTimeoutExpiry,
                                 ByteBuffer... buffers)

      Specified by:
        `doWrite` in class `WsRemoteEndpointImplBase`

    - #### updateStats

          protected void updateStats​(long payloadLength)

      Description copied from class: `WsRemoteEndpointImplBase`
      Hook for updating server side statistics. Called on every frame written (including when batching is enabled and the frames are buffered locally until the buffer is full or is flushed).
      Overrides:
        `updateStats` in class `WsRemoteEndpointImplBase`
      Parameters:
        `payloadLength` - Size of message payload

    - #### onWritePossible

          public void onWritePossible​(boolean useDispatch)

    - #### doClose

          protected void doClose()

      Specified by:
        `doClose` in class `WsRemoteEndpointImplBase`

    - #### getTimeoutExpiry

          protected long getTimeoutExpiry()

    - #### onTimeout

          protected void onTimeout​(boolean useDispatch)

    - #### setTransformation

          protected void setTransformation​(Transformation transformation)

      Overrides:
        `setTransformation` in class `WsRemoteEndpointImplBase`

    - #### getLock

          protected Lock getLock()

      Specified by:
        `getLock` in class `WsRemoteEndpointImplBase`