# 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 RemoteEndpoint

  `RemoteEndpoint.Async, RemoteEndpoint.Basic`

- ## Field Summary

  ### Fields inherited from class WsRemoteEndpointImplBase

  `messagePartInProgress, SENDRESULT_OK`

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `WsRemoteEndpointImplServer(SocketWrapperBase<?> socketWrapper, UpgradeInfo upgradeInfo, WsServerContainer serverContainer, WebConnection connection)`
  Constructs a server-side remote endpoint.

- ## Method Summary

  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()`
  Performs the actual close operation on the underlying connection.
  `protected void`
  `doWrite(SendHandler handler, long blockingWriteTimeoutExpiry, ByteBuffer... buffers)`
  Writes data to the underlying connection.
  `protected Lock`
  `getLock()`
  Returns the lock used for thread-safe operations.
  `protected long`
  `getTimeoutExpiry()`
  Returns the timeout expiry time in milliseconds.
  `protected final boolean`
  `isMasked()`
  Checks if frames should be masked.
  `protected void`
  `onTimeout(boolean useDispatch)`
  Handles a write timeout event.
  `void`
  `onWritePossible(boolean useDispatch)`
  Called when the underlying socket is ready for writing.
  `protected void`
  `setTransformation(Transformation transformation)`
  Sets the transformation for this endpoint.
  `protected void`
  `updateStats(long payloadLength)`
  Hook for updating server side statistics.

  ### Methods inherited from class 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 Object

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

- ## Constructor Details

  - ### WsRemoteEndpointImplServer

    public WsRemoteEndpointImplServer(SocketWrapperBase<?> socketWrapper, UpgradeInfo upgradeInfo, WsServerContainer serverContainer, WebConnection connection)
    Constructs a server-side remote endpoint.
    Parameters:
      `socketWrapper` - the socket wrapper
      `upgradeInfo` - the upgrade information
      `serverContainer` - the server container
      `connection` - the web connection

- ## Method Details

  - ### isMasked

    protected final boolean isMasked()
    Description copied from class: `WsRemoteEndpointImplBase`
    Checks if frames should be masked.
    Specified by:
      `isMasked` in class `WsRemoteEndpointImplBase`
    Returns:
      true if masking is required

  - ### 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 deadlock 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 deadlocked until the original message write times out
    The purpose of this method is to break the above deadlock. 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)
    Description copied from class: `WsRemoteEndpointImplBase`
    Writes data to the underlying connection.
    Specified by:
      `doWrite` in class `WsRemoteEndpointImplBase`
    Parameters:
      `handler` - the send handler
      `blockingWriteTimeoutExpiry` - the timeout expiry time
      `buffers` - the data buffers to write

  - ### 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)
    Called when the underlying socket is ready for writing.
    Parameters:
      `useDispatch` - whether to use a dispatch for callback

  - ### doClose

    protected void doClose()
    Description copied from class: `WsRemoteEndpointImplBase`
    Performs the actual close operation on the underlying connection.
    Specified by:
      `doClose` in class `WsRemoteEndpointImplBase`

  - ### getTimeoutExpiry

    protected long getTimeoutExpiry()
    Returns the timeout expiry time in milliseconds.
    Returns:
      the timeout expiry time

  - ### onTimeout

    protected void onTimeout(boolean useDispatch)
    Handles a write timeout event.
    Parameters:
      `useDispatch` - whether to use a dispatch for callback

  - ### setTransformation

    protected void setTransformation(Transformation transformation)
    Description copied from class: `WsRemoteEndpointImplBase`
    Sets the transformation for this endpoint.
    Overrides:
      `setTransformation` in class `WsRemoteEndpointImplBase`
    Parameters:
      `transformation` - the transformation to use

  - ### getLock

    protected Lock getLock()
    Description copied from class: `WsRemoteEndpointImplBase`
    Returns the lock used for thread-safe operations.
    Specified by:
      `getLock` in class `WsRemoteEndpointImplBase`
    Returns:
      the reentrant lock