In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-02 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/02 Report--
Today, I will talk to you about how to use WebSocket to create a chat room in SpringBoot. Many people may not know much about it. In order to make you understand better, the editor has summarized the following for you. I hope you can get something according to this article.
What is WebSocket1. Brief introduction
WebSocket protocol is a network protocol based on TCP, which implements full-duplex (Full-duplex) communication between the browser and the server-- allowing the server to actively send information to the client.
In the past, many websites used polling in order to implement push technology. Polling is a browser in which the browser issues a HTTP request to the server at a specific time interval (such as every 1 second), and then the server returns the latest data to the client. This traditional mode brings obvious disadvantages, that is, browsers need to constantly make requests to the server, but HTTP requests may contain long headers, in which the really valid data may be only a small part, which will obviously waste a lot of bandwidth and other resources.
In this case, HTML 5 defines the WebSocket protocol, which can better save server resources and bandwidth, and communicate in more real time. The WebSocket protocol was born in 2008, became an international standard in 2011, and is now supported by mainstream browsers.
Its biggest feature is that the server can actively push information to the client, and the client can also actively send information to the server, which is a real two-way equal dialogue, which belongs to a kind of server push technology. In WebSocket API, only one handshake is needed between the browser and the server, and a persistent connection can be directly created between the browser and the server for two-way data transmission.
two。 Advantages
Less control overhead
After the connection is created, the packet header used for protocol control is relatively small when data is exchanged between the server and the client. Without an extension, the header size is only 2 to 10 bytes for server-to-client content (depending on packet length), and an additional 4-byte mask is required for client-to-server content. This overhead is significantly reduced compared to having to carry a complete header every time a HTTP request is made.
Stronger real-time performance
Because the protocol is full-duplex, the server can actively send data to the client at any time. Compared with the HTTP request, it needs to wait for the client to initiate the request before the server can respond, and the delay is significantly less; even compared with similar long polling such as Comet, it can transmit data more times in a short time.
Keep connected
Unlike HTTP, Websocket needs to create a connection first, which makes it a stateful protocol, and then some state information can be omitted when communicating, while HTTP requests may need to carry status information (such as authentication, etc.) in each request.
Better binary support
Websocket defines binary frames, which make it easier to handle binary content than HTTP. Extensions can be supported. Websocket defines extensions that allow users to extend protocols and implement partially customized subprotocols. Such as some browsers support compression and so on.
Better compression effect
Compared to HTTP compression, Websocket can use the context of previous content with appropriate extension support, and can significantly increase the compression ratio when passing similar data.
After shaking hands, WebSocket communicates messages directly based on TCP, but WebSocket is only a very light layer above TCP. It only converts the byte flow of TCP into message flow (text or binary). How to parse the contents of these messages depends entirely on the application itself.
So in order to assist Client in negotiating the message format with Server, WebSocket retains a subprotocol field when shaking hands.
II. Stomp and WebSocket
STOMP, or Simple (or Streaming) Text Orientated Messaging Protocol, a simple (streaming) text-oriented message protocol, provides an interoperable connection format that allows STOMP clients to interact with any STOMP message broker (Broker). Because of its simple design and easy to develop client, STOMP protocol has been widely used in many languages and platforms.
The STOMP protocol is not designed for Websocket, it is a protocol that belongs to message queuing and is on a par with Amqp and Jms. Just because of its simplicity, it happens to be used to define the message body format of Websocket. It can be understood that Websocket combines the Stomp subprotocol segment to agree on the message content defined by the client and server on communication.
STOMP protocol is divided into client and server, the details are as follows.
1. STOMP server
The STOMP server is designed as a set of destination addresses to which clients can send messages. The STOMP protocol does not specify the format of the destination address, it is defined by the application that uses the protocol. For example, / topic/a, / queue/a, queue-an are all correct for the STOMP protocol. Applications can define different formats to indicate the meaning of different formats. For example, the application can define the publish and subscribe model that starts with / topic, and the message will be received by all consumer clients, while the peer-to-peer mode that starts with / user will only be received by one consumer client.
2. STOMP client
For the STOMP protocol, the client plays either of the following two roles:
As a producer, send a message to a specified address through a SEND frame
As a consumer, subscribe to a message by sending a SUBSCRIBE frame to a known address, and when the producer sends a message to this subscription address, other consumers subscribing to that address will receive the message through the MESSAGE frame.
In fact, WebSocket combined with STOMP is equivalent to building a message distribution queue, and the client can switch between the above two roles. The subscription mechanism ensures that a client message can be broadcast to multiple other clients through the server, and as a producer, peer-to-peer messages can be sent through the server.
3. STOMP frame structure COMMANDheader1:value1header2: value2Body^ @
Where ^ @ represents the line Terminator.
A STOMP frame consists of three parts: command, Header (header information), and Body (message body).
The command uses the UTF-8 encoding format, and the commands include SEND, SUBSCRIBE, MESSAGE, CONNECT, CONNECTED and so on.
Header also uses the UTF-8 encoding format, which is similar to HTTP's Header, such as content-length, content-type, and so on.
Body can be either binary or text. Note that Body and Header are separated by a blank line (EOL).
Let's take a look at an actual frame example:
SENDdestination:/broker/roomId/1content-length:57 {"type": "OUT", "content": "ossxxxxx-wq-yyyyyyyy"}
Line 1: indicates that this frame is a SEND frame and is a COMMAND field.
Line 2: the Header field, the destination address of the message to be sent, is the relative address.
Line 3: Header field, message body character length.
Line 4: blank line, interval between Header and Body.
Line 5: message body, which is a custom JSON structure.
For more details of STOMP protocol, please refer to STOMP's official website.
III. WebSocket event
Websocket uses the uniform resource identifier of ws or wss, similar to HTTPS, where wss represents Websocket on top of TLS. For example:
Ws://example.com/wsapiwss://secure.example.com/
Websocket uses the same TCP port as HTTP and can bypass most firewall restrictions. By default
The Websocket protocol uses port 80; when running on TLS, port 443 is used by default.
Event handler describes triggering when openSokcket onopen connection establishment triggers messageSokcket onmessage client to receive server data triggers errorSokcket onerror communication error triggers closeSokcket onclose link closure
The following is an example of a page using Websocket:
Var ws = new WebSocket ("ws://localhost:8080"); ws.onopen = function (evt) {console.log ("Connection open..."); ws.send ("Hello WebSockets!");}; ws.onmessage = function (evt) {console.log ("Received Message:" + evt.data); ws.close ();}; ws.onclose = function (evt) {console.log ("Connection closed.");}
Spring Boot provides the Websocket component spring-boot-starter-websocket to support the use of Websocket in a Spring Boot environment.
4. Websocket chat room
The dual-phase communication feature of Websocket is very suitable for the development of online chat rooms. Here we take an online multi-person chat room as an example to demonstrate the use of Spring Boot Websocket.
First of all, let's sort out the functions of chat rooms:
Support users to join chat rooms, corresponding to Websocket technology is to establish a connection to onopen
Support users to exit the chat room, corresponding to the Websocket technology is to close the connection to onclose
Support users to send messages in chat rooms. Corresponding to Websocket technology is to call onmessage to send messages.
Prompt if an exception is supported, corresponding to Websocket technology onerror
1. Page development
Use the frontend frame Bootstrap to render the page, and use HTML to build the page structure. The complete page content is as follows:
Chat room websocket chat room user name join chat room leave chat room send messages in groups
At the top, use textarea to draw a dialog box to display the contents of the chat room; in the middle part, add buttons for users to join and leave the chat room, with the entry for entering the user name above the button; and add the entry for sending messages at the bottom of the page, and the effect of the page is as follows:
Next, add the WebSocket communication code to the page:
$(document) .ready (function () {var urlPrefix = 'ws://localhost:8080/chat-room/'; var ws = null; $(' # user_join') .click (function () {var username = $('# in_user_name'). Val (); var url = urlPrefix + username; ws = new WebSocket (url)) Ws.onopen = function () {console.log ("establish a websocket connection...");}; ws.onmessage = function (event) {/ / message sent by the server $('# message_content') .append (event.data+'\ n');} Ws.onclose = function () {$('# message_content') .append ('user [' + username+'] has left the chat room!'); console.log ("close websocket connection.");}}) / / the client sends a message to the server $('# user_send_all') .click (function () {var msg = $('# in_room_msg'). Val (); if (ws) {ws.send (msg);}}) / / exit the chat room $('# user_exit') .click (function () {if (ws) {ws.close ();}});})
The main function of this code is to monitor the click events of the three buttons. When the user logs in, leaves, and sends messages, the corresponding WebSocket event is called and the information is transmitted to the server. At the same time, a WebSocket object is created when the page is opened, and the page will monitor WebSocket events. If the back-end service and the front-end communication room display the corresponding information on the page.
two。 Server-side development-introducing dependency org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-websocket
Mainly add Web and Websocket components.
-Startup class
The startup class needs to add @ EnableWebSocket to enable the WebSocket function.
@ EnableWebSocket@SpringBootApplicationpublic class WebSocketApplication {public static void main (String [] args) {SpringApplication.run (WebSocketApplication.class, args);} @ Bean public ServerEndpointExporter serverEndpointExporter () {return new ServerEndpointExporter ();}-request to receive
Before creating the server-side message receiving function, let's create a WebSocketUtils utility class to store the user information of the chat room online, as well as the ability to send messages. First, a global variable ONLINE_USER_SESSIONS is defined to store online users, and ConcurrentHashMap is used to improve the efficiency of concurrency.
Public static final Map ONLINE_USER_SESSIONS = new ConcurrentHashMap ()
Encapsulating the message sending method, first judging whether the single user exists before sending:
Public static void sendMessage (Session session, String message) {if (session = = null) {return;} final RemoteEndpoint.Basic basic = session.getBasicRemote (); if (basic = = null) {return;} try {basic.sendText (message);} catch (IOException e) {logger.error ("sendMessage IOException", e);}}
The messages in the chat room are visible to all online users, so each time the message is triggered is actually traversing all online users, sending messages to each online user.
Public static void sendMessageAll (String message) {ONLINE_USER_SESSIONS.forEach ((sessionId, session)-> sendMessage (session, message);}
Among them, ONLINE_USER_SESSIONS.forEach ((sessionId, session)-> sendMessage (session, message)) is a concise way to write JDK 1.8 forEach.
This allows us to import the methods and global variables of the utility class directly when we create the ChatRoomServerEndpoint class:
Import static com.neo.utils.WebSocketUtils.ONLINE_USER_SESSIONS;import static com.neo.utils.WebSocketUtils.sendMessageAll
You need to add @ ServerEndpoint ("url") to the receiving class to represent the WebSocket information that listens to this address.
@ RestController@ServerEndpoint ("/ chat-room/ {username}") public class ChatRoomServerEndpoint {}
When the user logs in to the chat room, the user information is added to the ONLINE_USER_SESSIONS and the people in the chat room are notified. Where the @ OnOpen annotation is consistent with the onopen event in the front end, indicating that it is triggered when the user establishes a connection.
@ OnOpenpublic void openSession (@ PathParam ("username") String username, Session session) {ONLINE_USER_SESSIONS.put (username, session); String message = "Welcome to the chat room [" + username + "]!" ; logger.info ("user login:" + message); sendMessageAll (message);}
When a user in a chat room sends a message, synchronize the message to the owner of the chat room. Where @ OnMessage listens for events that send messages.
@ OnMessagepublic void onMessage (@ PathParam ("username") String username, String message) {logger.info ("send message:" + message); sendMessageAll ("user [" + username + "]:" + message);}
When the user leaves the chat room, the user information needs to be removed from the ONLINE_USER_SESSIONS and notified to other users online, where @ OnClose listens for the user disconnection event.
@ OnClosepublic void onClose (@ PathParam ("username") String username, Session session) {/ / the current Session removes ONLINE_USER_SESSIONS.remove (username); / / and notifies others that the current user has left the chat room sendMessageAll ("user [" + username + "] has left the chat room!) ; try {session.close ();} catch (IOException e) {logger.error ("onClose error", e);}}
When an exception occurs in the WebSocket connection, the @ OnError event is triggered, in which you can record the error exception information and close the user connection.
@ OnErrorpublic void onError (Session session, Throwable throwable) {try {session.close ();} catch (IOException e) {logger.error ("onError excepiton", e);} logger.info ("Throwable msg" + throwable.getMessage ());}
At this point, our server content has been developed.
-Test
Start the spring-boot-websocket project and enter the address http://localhost:8080/ in the browser to open two pages for testing.
In the first page, log in to the chat room with the user "Xiao Wang", and the second page log in to the chat room as "Xiao Zhang".
Xiao Wang: who are you? Xiao Zhang: guess Xiao Wang: I've guessed it! Xiao Zhang: what did you guess? Xiao Wang: guess? Xiao Zhang: … Xiao Zhang left the chat room.
In the dialogue between Xiao Wang and Xiao Zhang in the two page modes, you can see the display effect of the two pages. Both pages can display the latest chat content without refresh in real time. The final display effect of the page is as follows:
After reading the above, do you have any further understanding of how to use WebSocket to create a chat room in SpringBoot? If you want to know more knowledge or related content, please follow the industry information channel, thank you for your support.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.