# API Overview

This section discusses the basic concepts of the Java WebSocket API and will help you gain a decent understanding of its building blocks. Luckily, the API itself is pretty compact which made it easy to ensure that this chapter touches upon **all it's components**. (most of) The items presented in this chapter have been covered via dedicated chapters throughout this book.

## Server and client mode

To start with, let's understand what does server and client mean in the context of WebSocket in general

### WebSocket Server endpoint

A server side component which

* implements some business logic
* _publishes_ itself i.e. makes itself discoverable to potential clients (over a certain host and port combination)
* gets _triggered_ when clients connect to it

### WebSocket Client endpoint

* implements some business logic (just like it's server side counterpart)
* it _connects to existing_ WebSocket (server) endpoints

The Java WebSocket API provides both server and client side components

| Component type | Description                                                                                                                      |
| -------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| Server         | everything in the `javax.websocket.server` package                                                                               |
| Client         | the contents of `javax.websocket` package consist of client side APIs as well as ones which are _common_ to both server & client |

Client API components are as follows - `ClientEndpoint`, `ClientEndpointConfig`, `ClientEndpointConfig.Builder`, `ClientEndpointConfig.Configurator`, `WebSocketContainer` (helps connect to existing WebSocket server endpoints)

> Client side API has been covered in a separate chapter

## Supported message formats

The WebSocket specification supports two on-wire data formats - text and binary. The Java WebSocket API supports these (obviously) and adds capability to work with Java objects as well as _health check_ messages (ping-pong) defined by the specification

| Supported message type | Description                                                                                                                                                                                                                                  |
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Text                   | Any textual data (`java.lang.String`, primitives or their equivalent wrapper classes)                                                                                                                                                        |
| Binary                 | Binary data (e.g. audio, image etc.) represented by a `java.nio.ByteBuffer` or a `byte[]` (byte array)                                                                                                                                       |
| Java objects           | The API makes it possible to work with native (Java objects) representations in your code and use custom _transformers_ (encoders/decoders) to convert them into compatible on-wire formats (text, binary) allowed by the WebSocket protocol |
| Ping, Pong             | A `javax.websocket.PongMessage` is the acknowledgement sent by a WebSocket peer in response to a health check (ping) request                                                                                                                 |

> Deep dive of sending and recieving different types of messages will covered in subsequent chapters

## Container Abstraction

The following APIs provide a high level abstraction of the WebSocket container (runtime)

| API                                      | Description                                                                                                                                                                                                                                                    |
| ---------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `javax.websocket.WebSocketContainer`     | Provides a high level view of the container, allows client endpoint activation and connection to an existing (WebSocket) server, enforce global/common properties (idle connection timeout, message size, asynchronous send timeout) relevant to all endpoints |
| `javax.websocket.server.ServerContainer` | Server side derivative of the `WebSocketContainer` which allows programmatic deployment of WebSocket endpoints                                                                                                                                                 |
| `javax.websocket.ContainerProvider`      | Provides access to an instance of the underlying `WebSocketContainer`                                                                                                                                                                                          |

```
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
container.setDefaultMaxSessionIdleTimeout(60000); //1 min. idle session timeout
container.connectToServer(ChatClient.class, URI.create("ws://letschat:8080")); //connecting to a websocket server

//fetching the ServerContainer instance (from within a Server endpoint)
ServerContainer container = (ServerContainer) session.getContainer();
```

## RemoteEndpoint

WebSocket is a protocol using which two peers (client and server) communicate with each other. The `javax.websocket.RemoteEndpoint` interface is an abstraction which represents the peer at the _other end_

It is available is two avatars

| Mode         | Description                                                                                                                                                                                             |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Synchronous  | Blocking API (sending messages). Executed using `javax.websocket.RemoteEndpoint.Basic`                                                                                                                  |
| Asynchronous | Controlled using `javax.websocket.RemoteEndpoint.Async`. The caller is not blocked when using this API. It can get a `java.util.concurrent.Future` object in return or supply a callback implementation |

```
//Getting a handle to the remote endpoint

RemoteEndpoint.Basic basicPeerConnection = session.getBasicRemote();
RemoteEndpoint.Async asyncPeerConnection = session.getAsyncRemote();
```

## Endpoint

A `javax.websocket.Endpoint` is a class which represents the WebSocket endpoint itself – either a server or a client. The Java WebSocket API provides both annotation and programmatic APIs (both will been explored in detail later) to develop endpoints. This class is designed for extension (since it is _abstract_) and is fit for scenarios where a programmatic style is preferred over annotation driven (declarative) implementation

```
//a bare bone implementation of a programmatic endpoint

public class ProgrammaticEndpointExample extends Endpoint {
  private Session session;
  @Override
  public void onOpen(Session session, EndpointConfig config) {
    this.session = session;
    try {
      //sends back the session ID to the peer
      this.session.getBasicRemote().sendText("Session ID: " +   this.session.getId());
      } 
    catch (IOException ex) {
        throw new RuntimeException(ex);
      }
}
```

> It is important to understand that `Endpoint` and `RemoteEndpoint` represent different concepts altogether

![](https://2698670403-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M3y20se5T5tgBXBcWyM%2F-M3y23Fq1q0Wn8xweQA9%2F-M3y24k36g-A0CW9Q-Rf%2Fwebsocket_endpoint_remoteEP.jpg?generation=1585883940347878\&alt=media)

In the above diagram

* **WSE** is both a `RemoteEndpoint` (from the perspective of it's connected peers) as well as an Endpoint (assuming its implemented by extending the `javax.websocket.Endpoint` class)
* Each of the peers (Peer 1,2,3,4… n) are `RemoteEndpoint`(s) from the perspective of the WSE (the websocket server with which they are interacting)

## Session

The concept of a WebSocket session (represented by `javax.websocket.Session`) is not very different than that of a HTTP Session: it encapsulates the interaction between two endpoints (peers). The conversation between two endpoints consists of events like – connection initialization, message exchange, connection termination, error transmission etc.

* Each connection b/w a peer and the WebSocket server endpoint is represented by a unique `Session` object (refer previous diagram)
* Allows communication b/w a server-client pair by exposing a `javax.websocket.RemoteEndpoint` object (discussed later)

```
//some of the common methods in the Session interface

Set<Session> openSessions = session.getOpenSessions();
boolean isOpen = session.isOpen();
Map<String, String> pathParameters = session.getPathParameters();
Map<String, Object> userProperties = session.getUserProperties();
Principal userPrincipal = session.getUserPrincipal();
```

## Declarative & Programmatic models

The annotations in the API offer a declarative model for building WebSocket based applications whereas the programmatic style lean towards a more classical way of development model i.e. using _inheritance_.

| Component    | Description                                                                    |
| ------------ | ------------------------------------------------------------------------------ |
| Declarative  | Powered by the `@ServerEndpoint` and `@ClientEndpoint` _annotations_           |
| Programmatic | Extend (inherit from) the `javax.websocket.Endpoint` class to adopt this style |

## Encoders & Decoders

Think of them as hooks provided by the WebSocket API, which allow you to plugin your custom implementation that takes care of converting your Java objects (part of your logic, domain model etc.) to/from the on-wire representations supported by the WebSocket protocol i.e. text and binary

| Component | Description                                                                                                   |
| --------- | ------------------------------------------------------------------------------------------------------------- |
| `Encoder` | A `javax.websocket.Encoder` helps convert from Java object to text or binary                                  |
| `Decoder` | Need a `java.websocket.Decoder` implementation to convert a text or binary payload into a Java representation |

## Configuration

In the context of the Java WebSocket API, configuration is nothing but the attributes/properties (deployed path, encoders, decoders, extensions, subprotocols) related to an endpoint (server or client) and is represented by the `javax.websocket.EndpointConfig` interface. It is further extended by `javax.websocket.server.ServerEndpointConfig` and `javax.websocket.ClientEndpointConfig` which are the server and client counterparts respectively

## Asynchronous constructs

Sending messages to peers need not always be a blocking call. One can choose to embrace the asynchronous style (as mentioned in the **RemoteEndpoint** section)

The `SendHandler`, `SendResult` interfaces (in the `javax.websocket` package) enable asynchronous messaging in WebSocket endpoints

| Component     | Description                                                                                              |
| ------------- | -------------------------------------------------------------------------------------------------------- |
| `SendHandler` | A callback interface to define actions to be taken after message sending process hsa completed or failed |
| `SendResult`  | Provides a way to access the result of the send process                                                  |

## WebSocket Extension

| Component                             | Description                                                            |
| ------------------------------------- | ---------------------------------------------------------------------- |
| `javax.websocket.Extension`           | Represents a WebSocket extension. Has a name and associated parameters |
| `javax.websocket.Extension.Parameter` | Represents the parameter of an extension                               |

## Exceptions

All the exceptions defined by this API are

* checked
* part of the `javax.websocket` package

| Exception             | Description                                                                                                                                     |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `DeploymentException` | Represents an issue that might ave occurred during deployment of a server-side endpoint or while establishing a connection using the Client API |
| `DecodeException`     | Can occur during conversion of text/binary to a custom Java object                                                                              |
| `EncodeException`     | Can occur during transformation of a Java object into text/binary format                                                                        |
| `SessionException`    | Denotes that a problem has occurred with a specific `Session`                                                                                   |

## Miscellaneous

### Path parameters

In case of an annotated server endpoint (details in the next chapter), `javax.webocket.PathParam` helps inject the path parameters (from the URI specified in the `@ServerEndpoint` annotation) into annotated websocket lifecycle methods

```
//Using @PathParam

@ServerEndpoint(value = "/letschat/{login-id}")
   public class WebChatEndpoint {
   @OnOpen
   public void connected(Session session, @PathParam("login-id") String   loggedInUser){
   //save the logged in user id
   session.getUserProperties().put("USERNAME", loggedInUser);
   }
....
}
```

### WebSocket connection handshake

Instances of `HandshakeRequest` and `HandshakeResponse` (from the `javax.websocket` pacakge), allow access to the state of communication during establishment (handshake) of the WebSocket connection

### Communicating connection termination details

`javax.websocket.CloseReason` captures the details (reason) for the termination of a WebSocket connection. `javax.websocket.CloseReason.CloseCode` is a **marker** interface for different reason codes and `javax.websocket.CloseReason.CloseCodes` (_please note the '**s**' at the end_) contains an enumeration of ready-to-use codes (outlined in the [following section of the WebSocket RFC specification](https://tools.ietf.org/html/rfc6455#section-7.4.1)) - give link

```
//Why did the connection close?

@OnClose
public void disconnected(Session session, CloseReason reason){
  String peer = (String) session.getUserProperties().get("USERNAME");
  CloseReason.CloseCode closeReasonCode = reason.getCloseCode();
  String closeReasonMsg = reason.getReasonPhrase();
  System.out.println("User "+ peer + " disconnected. Code: "+ closeReasonCode + ", Message: "+ closeReasonMsg);
}
```

## Coming up...

The next chapter will guide you through the **Programming Models** can be adopted while using the Java WebSocket API
