From today on, roll up your sleeves and follow me
Tip: if you have any questions please contact private, below the source code address, please take it yourself
preface
Using Spring Boot makes it very easy and fast to set up projects, so we don’t have to worry about compatibility between frameworks, applicable versions, etc. We can use anything we want, just add a configuration.
Tip: The following is the body of this article, the following cases for reference
I. Technical introduction
1. What is WebSocket?
Two, the use of steps
1. Import maven libraries
The code is as follows (example) :
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.41.</version> <relativePath/> </parent> <dependencies> <! Websocket dependency --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> <dependency> <groupId>org.java-websocket</groupId> <artifactId>Java-WebSocket</artifactId> <version>LATEST</version> </dependency> </dependencies>Copy the code
2. Example of using WebSocket
WebSocket configuration class:
package com.hyh.websocket.config;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/** * WebSocket configuration ** @author: HEYUHUA * @date: 2021/1/7 11:54 */
@Configuration
public class WebSocketConfig {
/** * Inject a ServerEndpointExporter, which automatically registers the WebSocket endpoint declared with the @ServerEndpoint annotation */
@Bean
public ServerEndpointExporter serverEndpointExporter(a) {
return newServerEndpointExporter(); }}Copy the code
Service interface class:
package com.hyh.websocket;
import javax.websocket.Session;
/** * WebSocket server interface ** @author: heyuhua * @date: 2021/1/7 11:51 */
public interface IWebSocketServer {
Call ** @param session */
void onOpen(Session session, String userId);
/** * call ** @param message * @param session */
void onMessage(String message, Session session);
/** * connection close call */
void onClose(a);
Call ** @param session * @param error */ when an error or exception occurs
void onError(Session session, Throwable error);
}
Copy the code
WebSocket support classes:
package com.hyh.websocket.support;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.hyh.utils.common.StringUtils;
import com.hyh.websocket.IWebSocketServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PathVariable;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
** @author: heyuhua * @date: 2021/1/7 14:07 */
public class WebSocketServerSupport implements IWebSocketServer {
private static Logger LOG = LoggerFactory.getLogger(WebSocketServerSupport.class);
/** * static variable used to record the number of current online connections. It should be designed to be thread-safe. * /
private static int onlineCount = 0;
/** * A thread-safe Set for the Concurrent package, used to hold each client's corresponding MyWebSocket object. * /
private static ConcurrentHashMap<String, WebSocketServerSupport> webSocketMap = new ConcurrentHashMap<>();
/** * Connects to a client through which to send data to the client */
private Session session;
/** * receive userId */
private String userId;
/** * Connection established successfully called method */
@OnOpen
public void onOpen(Session session, @PathParam("userId") String userId) {
this.session = session;
this.userId = userId;
if (webSocketMap.containsKey(userId)) {
webSocketMap.remove(userId);
webSocketMap.put(userId, this);
} else {
webSocketMap.put(userId, this);
addOnlineCount();
}
LOG.info("User Connection :" + userId + ", current online population is :" + getOnlineCount());
try {
sendMessage("Connection successful");
} catch (IOException e) {
LOG.error("Users." + userId + ", network exception!!!!!!"); }}/** * the connection closes the called method */
@OnClose
public void onClose(a) {
if (webSocketMap.containsKey(userId)) {
webSocketMap.remove(userId);
// Delete from set
subOnlineCount();
}
LOG.info("User logout :" + userId + ", current online population is :" + getOnlineCount());
}
/** * @param message the message sent by the client */
@OnMessage
public void onMessage(String message, Session session) {
LOG.info("User message :" + userId + ", a message:" + message);
// You can send group messages
// Save the message to the database, redis
if (StringUtils.isNotBlank(message)) {
try {
// Parse the sent packet
JSONObject jsonObject = JSON.parseObject(message);
// Append the sender (to prevent string modification)
jsonObject.put("fromUserId".this.userId);
String toUserId = jsonObject.getString("toUserId");
// To the websocket corresponding to the toUserId user
if (StringUtils.isNotBlank(toUserId) && webSocketMap.containsKey(toUserId)) {
webSocketMap.get(toUserId).sendMessage(jsonObject.toJSONString());
} else {
LOG.error("Requested userId:" + toUserId + "Not on this server");
// Otherwise not on the server, send to mysql or redis}}catch(Exception e) { e.printStackTrace(); }}}/** * @param session @param error */
@OnError
public void onError(Session session, Throwable error) {
LOG.error("User error :" + this.userId + ",原因:" + error.getMessage());
error.printStackTrace();
}
/** * implement server active push */
public void sendMessage(String message) throws IOException {
this.session.getBasicRemote().sendText(message);
}
/** * Send a custom message */
public static void sendInfo(String message, @PathParam("userId") String userId) throws IOException {
LOG.info("Send a message to :" + userId + ", message :" + message);
if (StringUtils.isNotBlank(userId) && webSocketMap.containsKey(userId)) {
webSocketMap.get(userId).sendMessage(message);
} else {
LOG.error("User" + userId + ", not online!); }}public static synchronized int getOnlineCount(a) {
return onlineCount;
}
public static synchronized void addOnlineCount(a) {
WebSocketServerSupport.onlineCount++;
}
public static synchronized void subOnlineCount(a) { WebSocketServerSupport.onlineCount--; }}Copy the code
3. Configuration file
The code is as follows (example) :
server:
port: 8088
Copy the code
Unit testing
The test code is as follows (example) :
import com.hyh.websocket.support.WebSocketServerSupport;
import org.springframework.stereotype.Component;
import javax.websocket.server.ServerEndpoint;
** @author: heyuhua * @date: 2021/1/7 15:56 * /
@ServerEndpoint("/websocket/{userId}")
@Component
public class WebSocketServer extends WebSocketServerSupport {
// Available browser test, WebSocketServer class in com.hyh.core.web of hyh-boot-ore
/ / open the websocket test online address, enter the address ws: / / localhost: 8088 / websocket / 1 can be tested
// The implementation methods are all in the WebSocketServerSupport class, yes, the purpose is to allow you to integrate directly to use
}
Copy the code
conclusion
For more usage, please click below to view the source code. Does it feel very simple? Follow me as I reveal more advanced usage of Quartz
Source code: click here to view the source code.