WebSocket
Why use the advanced version? The new technology must have solved the technical problem
Defects of Http protocol:
The communication can only be initiated by the client, which requires a kind of ability that the server can actively push to - websocket
**websocket: * * this is a two-way communication capability, also known as "full duplex"
websocket is initiated by the browser
Generally, we use http to call short connection better
websocket is called: long connections are more reusable
Applicable to different scenarios
Here, we still use http to link, but after connecting, we transmit information until it is disconnected
In essence, the bottom layer of http is tcp, which supports full duplex
Protocol identifier http://127.0.0.1:8080 ws://127.0.0.1:7777
GET ws://127.0.0.1:7777 HTTP/1.1 Host: 127.0.0.1 Upgrade: websocket # Upgrade to ws Connection: Upgrade # This link needs to be upgraded Sec-WebSocket-key: client-random-string ... # Identify encryption related information
Response results
HTTP/1.1 101 Upgrade: websocket Connection: Upgrade
The response code 101 indicates that the protocol needs to be changed to websocket
After the connection is established, text information and binary information are supported.
Principle of Websocket implementation:
Establish the connection (handshake and answer) through http protocol. After establishing the connection, http is no longer used. tcp itself supports two-way communication, so it can achieve the effect of "full duplex".
Websocket Application demo
Server code
public class WebSocketServer { public static void main(String[] args) { //You can customize the number of threads EventLoopGroup bossGroup = new NioEventLoopGroup(1); // Number of threads created by default = number of CPU processors * 2 EventLoopGroup workerGroup = new NioEventLoopGroup(); ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .handler(new LoggingHandler()) //When the current connection is blocked, the BACKLOG represents the length of the event blocking queue .option(ChannelOption.SO_BACKLOG, 128) //Set the connection to remain active .childOption(ChannelOption.SO_KEEPALIVE, true) .childHandler(new WebSocketInitialzer()); try { ChannelFuture future = serverBootstrap.bind(7777).sync(); future.channel().closeFuture().sync(); } catch (InterruptedException e) { e.printStackTrace(); } finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } }
Server initializer
public class WebSocketInitialzer extends ChannelInitializer<Channel> { @Override protected void initChannel(Channel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); //Another way to add codecs pipeline.addLast(new HttpServerCodec()); // The processor written in block mode is suitable for processing big data pipeline.addLast(new ChunkedWriteHandler()); //polymerization pipeline.addLast(new HttpObjectAggregator(512 * 1024)); /* * At this time, we need to declare that we are using the websocket protocol * netty The corresponding processor is also prepared for websocket, and the access path is set * At this time, we only need to visit ws://127.0.0.1:7777/hello * This handler upgrades the http protocol to websocket and uses 101 as the response code * */ pipeline.addLast(new WebSocketServerProtocolHandler("/hello")); pipeline.addLast(new WebSocketHandler()); } }
Server processor
The unit used for communication is called frame
Client: cut the message into multiple frames when sending
Server: reassemble the associated frames when receiving
/* * Generics represent units that process data * TextWebSocketFrame : Text information frame * */ public class WebSocketHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> { @Override protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame textWebSocketFrame) throws Exception { //You can directly call text to get the information in the text information frame System.out.println("msg:" + textWebSocketFrame.text()); Channel channel = ctx.channel(); //We can create a new object and put the information that the server needs to return into it TextWebSocketFrame resp = new TextWebSocketFrame("hello client from websocket server"); channel.writeAndFlush(resp); } }
Writing websocket front end
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <script> var socket; // Judge whether the current browser supports websocket if (!window.WebSocket) { alert("I won't support it websocket") } else { <!-- establish websocket Connection object--> socket = new WebSocket("ws://127.0.0.1:7777/hello"); //Set the method to start the connection socket.onopen = function (ev) { var tmp = document.getElementById("respText"); tmp.value = "The connection has been opened"; } //Set the method to close the connection socket.onclose = function (ev) { var tmp = document.getElementById("respText"); tmp.value = tmp.value + "\n" + "The connection has been closed"; } //Set the method of receiving data socket.onmessage = function (ev) { var tmp = document.getElementById("respText"); tmp.value = tmp.value + "\n" + ev.data; } } function send(message) { if (!window.socket) { return } /* * Judge the state of socket * connecting Connecting closing closing * closed Failed to close or open connection * open The connection can communicate normally * */ if (socket.readyState == WebSocket.OPEN) { socket.send(message); } else { alert("Connection not open"); } } </script> <!--Prevent automatic form submission--> <form onsubmit="return false"> <textarea name="message" style="height: 400px;width: 400px"></textarea> <input type="button" value="send out" onclick="send(this.form.message.value)"> <textarea id="respText" style="height: 400px;width: 400px"></textarea> </form> </body> </html>
[Client]
var ws = new WebSocket("ws://127.0.0.1:7777/hello"); ws.onopen = function(ev){ ws.send("hello"); //Send data after establishing connection }
Design a style
There is a text box on the left and right, with a send button in the middle.
The left text box is used to send data, and the right text box is used to display data.
Demonstration effect
Start service send message
Messages received by the server
Summary
- websocket is generally used for reusable connections, and http is generally used for short links
- websocket solves the pain point that http connection can only be initiated by the client