How to implement WebSocket in Tomcat
The WebSocket protocol belongs to the HTML5 standard, and more and more browsers have natively supported WebSocket, which allows clients and servers to achieve two-way communication. After establishing a WebSocket connection between the client and the server, the server-side message can be sent directly to the client, thus breaking the traditional request response mode and avoiding meaningless requests. For example, the traditional way may use AJAX to continuously request the server side, while WebSocket can directly send data to the client and the client does not have to request it. At the same time, thanks to the native browser support, writing client applications has become more convenient and no need to rely on third-party plug-ins. In addition, the WebSocket protocol abandons the cumbersome request headers of the HTTP protocol, but transmits it in the form of data frames, which is more efficient.
The picture shows the process of WebSocket protocol communication. First, the client will send a handshake package to tell the server that I want to upgrade to WebSocket. I don’t know whether your server agrees. At this time, if the server supports WebSocket protocol, it will return a handshake package to tell the client that there is no problem and the upgrade has been confirmed. Then a WebSocket connection was successfully established, which supports two-way communication and sends messages using the data frame format of the WebSocket protocol.
The handshake process needs to be explained. In order to make the WebSocket protocol compatible with the existing HTTP protocol Web architecture, the handshake of the WebSocket protocol must be based on the HTTP protocol. For example, the client will send HTTP messages similar to the following to the server request to upgrade to the WebSocket protocol. The Upgrade: websocket tells the server that I want to upgrade the protocol:
GET ws://localhost:8080/hello HTTP/1.1 Origin: http://localhost:8080 Connection: Upgrade Host: localhost:8080 Sec-WebSocket-Key: uRovscZjNol/umbTt5uKmw== Upgrade: websocket Sec-WebSocket-Version: 13
At this time, if the server supports the WebSocket protocol, it will send a message that agrees to the client's upgrade protocol. The specific message is similar to the following, where Upgrade: websocket tells the client that I agree to your upgrade protocol:
HTTP/1.1 101 WebSocket Protocol Handshake Date: Fri, 10 Feb 2016 17:38:18 GMT Connection: Upgrade Server: Kaazing Gateway Upgrade: WebSocket Sec-WebSocket-Accept: rLHCkw/SKsO9GAH/ZSFhBATDKrU=
After completing the handshake as above, the HTTP protocol connection is broken. Next, you start using the WebSocket protocol to communicate between the two parties. This connection is still the original TCP/IP connection, and the port is still the original 80 or 443.
Here is a simple example of writing WebSocket in Tomcat:
public class HelloWebSocketServlet extends WebSocketServlet { private static List<MessageInbound> socketList = new ArrayList<MessageInbound>(); protected StreamInbound createWebSocketInbound(String subProtocol,HttpServletRequest request){ return new WebSocketMessageInbound(); } public class WebSocketMessageInbound extends MessageInbound{ protected void onClose(int status){ super.onClose(status); socketList.remove(this); } protected void onOpen(WsOutbound outbound){ super.onOpen(outbound); socketList.add(this); } @Override protected void onBinaryMessage(ByteBuffer message) throws IOException { } @Override protected void onTextMessage(CharBuffer message) throws IOException { for(MessageInbound messageInbound: socketList){ CharBuffer buffer = CharBuffer.wrap(message); WsOutbound outbound = messageInbound.getWsOutbound(); outbound.writeTextMessage(buffer); outbound.flush(); } } }}This servlet must inherit the WebSocketServlet, and then create a WebSocketMessageInbound class that inherits MessageInbound. Populate the onClose, onOpen, onBinaryMessage and onTextMessage into this class to complete the logic of each event. OnOpen will be called when a WebSocket connection is established, onClose will be called when a WebSocket is closed, onBinaryMessage is called when a client data is received under Binary mode, and onTextMessage is called when a client data is received under Text mode. The above code implements the effect of a broadcast.
According to the above processing logic, Tomcat's integration of WebSocket will not be too difficult. It means that if you encounter a WebSocket protocol request when processing a request, you will do special processing, keep the connection and call the onClose, onOpen, onBinaryMessage and onTextMessage of the WebSocketServlet's MessageInbound methods at the appropriate time. Since WebSocket is generally recommended to be used in NIO mode, look at the NIO mode integration WebSocket protocol.
As shown in the figure, if the client connection of the WebSocket is received by the receiver and registered in the NioChannel queue, the Poller component keeps resting on whether there is a NioChannel to handle. If so, it will go through the processing pipeline to the Servlet inheriting the WebSocketServlet. The doGet method of the WebSocketServlet will handle the WebSocket handshake and tell the return client to agree to the upgrade agreement. Later, Poller continued to take turns to take off related NioChannel. Once it was discovered that the pipeline using the WebSocket protocol was used, it would call the MessageInbound method to complete the processing of different events, thereby achieving support for the WebSocket protocol.
Thank you for reading, I hope it can help you. Thank you for your support for this site!