preface

Today, I have nothing to do, so I’ll take a look at the WebSocket protocol. Let’s take a quick look.

What is the WebSocket

What is a WebSocket? WebSocket is a protocol for full duplex communication over a single TCP connection. This is an official way of saying that in a TCP connection, two communicating parties can communicate with each other. For example, when user A and USER B are talking on the phone, user B can also talk to communicate with each other. This is called full-duplex communication. The corresponding is simplex communication, and half duplex communication, simplex communication is communication only from A to B, such as computers and printers. In half duplex communication, AB can communicate with each other, but only one-way communication can be carried out at the same time, such as intercom.

What’s the difference between WebSocket and HTTP

The same

Both are built on TOP of TCP, through which data is transmitted.

The difference between

HTTP is a one-way protocol, that is, the server can send data to the browser only after the browser requests resources from the server, but the server cannot actively transmit data to the browser. It is divided into long connection and short connection. The short connection requires three handshakes for each HTTP request before sending its own request. Each request corresponds to a response. A long connection is a TCP connection that is kept open for a short period of time.

WebSocket is a two-way communication protocol. After a connection is established, both the WebSocket server and the client can actively send or receive data to each other, just like Socket. The difference is that WebSocket is a simple simulation protocol based on the Web. WebSocket requires handshake connection. Similar to TCP, WebSocket requires handshake connection between the client and server. After the connection is successful, the client can communicate with the server. When WebSocket establishes handshake connection, data is transmitted through HTTP protocol, “GET/chat HTTP/1.1”, which only uses some simple HTTP fields. However, after the connection is established, the actual data transfer phase does not require the HTTP protocol.

use

WebSocket solves the problem that the client must go through a long round of inquiries when sending multiple HTTP requests to the server resource browser.

Use WebSocket to build a multiplayer chat system

  1. The WebSocket JAR package is introduced

Gradle:

Compile group: 'org.springframework.boot', name: 'spring-boot-starter-websocket', version: '2.1.8.RELEASE'Copy the code

Maven:

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> < version > 2.1.8. RELEASE < / version > < / dependency >Copy the code

  1. Add WebSocket support

Inject ServerEndpointExporter, and this bean will automatically register the Websocket endpoint declared with the @ServerEndpoint annotation.

import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.server.standard.ServerEndpointExporter; /** * @author: zp * @Date: 2019-09-18 10:03 * @Description: */ @Configuration public class AppConfiguration { @Bean public ServerEndpointExporter serverEndpointExporter(){ return new ServerEndpointExporter(); }}Copy the code

  1. Create an implementation class for WebSocket

The value in @serverendpoint (“/webSocket/{page}”) is the address that needs to be accessed, similar to @requestMapping in Controller. Then implement @onopen (to open a connection), @onClose (to close a connection),@onMessage (to receive a message), and @error (to raise an exception).

import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import javax.websocket.*; import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; import java.io.IOException; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.atomic.AtomicInteger; /** * @author: zp * @Date: 2019-09-20 15:12 * @Description: */ @Component @ServerEndpoint("/webSocket/{page}") public class WebSocket { private Logger log = LoggerFactory.getLogger(this.getClass()); Private static AtomicInteger onlinePersons = new AtomicInteger(0); Private static Map<String,Set> roomMap = new ConcurrentHashMap(8); private static Map<String,Set> roomMap = new ConcurrentHashMap(8); @OnOpen public void open(@PathParam("page") String page, Session session) throws IOException { Set set = roomMap.get(page); If (set == null){set = new CopyOnWriteArraySet(); // If the room is new, create a mapping, if the room already exists, put the user in it. set.add(session); roomMap.put(page,set); }else{ set.add(session); } / / room number + 1 onlinePersons. IncrementAndGet (); Log.info (" new user {} enters chat, room number :{}", session.getid (),onlinePersons); } @onclose public void close(@pathParam ("page") String page, Session Session){ If (roommap.containsKey (page)){roommap.get (page).remove(session); } / / room number 1 onlinePersons decrementAndGet (); Log.info (" user {} quit chat, room number :{}", session.getid (),onlinePersons); } @OnMessage public void reveiveMessage(@PathParam("page") String page, Session Session,String message) throws IOException {log.info(" Received data from user {} :{}", session.getid (),message); String MSG = session.getid ()+" : "+ message; Set<Session> sessions = roomMap.get(page); For (Session s: sessions){s.getbasicRemote ().sendText(MSG); } } @OnError public void error(Throwable throwable){ try { throw throwable; } catch (Throwable e) {log.error(" unknown error "); }}}Copy the code

Write a super simple page to test it out

Front order, write not a nice UI, sorry ~

< HTML >< head> <meta charset="UTF-8"></meta> <title> Springboot project WebSocket demo</title> </head> <body> < H3 > Springboot project Websocket test demo</ H3 > < H4 > Test Description </ H4 > < H5 > Data data in the text box, click "send test", the data in the text box will be sent to the background WebSocket, after receiving the background, the data will be pushed to the front end, displayed below; Click close connection to close the Websocket. Can track the code, understand the specific flow; </h5> <br /> <input ID ="text" type="text" /> <button onclick="send()"> </button> <hr /> <button </button> <hr /> <div id="message"></div> <script> var websocket = null; If (' WebSocket in Windows) {WebSocket = new WebSocket (ws: / / 127.0.0.1:9999 / WebSocket / 1 "); }else{alert(" Your browser does not support websocket"); } websocket.onerror = function(){setMessageInHtml("send error! ); } websocket.onopen = function(){setMessageInHtml(" Connect successfully!" ) setTimeout(function(){setMessageInHtml(" Welcome here!" )},2000)} websocket. onMessage = e => setMessageInHtml(e.ata) websocket.onclose = function(){setMessageInHtml(" Disconnect! ") ) } window.onbeforeunload = function(){ clos(); } function setMessageInHtml(message){ document.getElementById('message').innerHTML += message+"</br>"; } function clos(){websocket.close(3000," forced close "); } function send(){ var msg = document.getElementById('text').value; websocket.send(msg); } </script> </body> </html>Copy the code

test

Afterword.

Hope we have a little harvest every day ~

Follow me if you find it useful