1. Create a new springboot project and add a maven dependency
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency>
The file directory structure is as follows:
2. Create websocket server class
MoneyServer.java
/** * @author Page * @date 2019-07-02 10:00 * @description websocket service */ @Component @Slf4j @ServerEndpoint(value = "/money/{userId}", decoders = { MessageDecoder.class,}, encoders = {MessageEncoder.class,}, configurator = MoneyRepayConfig.class) public class MoneyServer { private static final Map<String, Session> SESSION_MAP = new HashMap<>(); @OnOpen public void connect(Session session, @PathParam("userId") String userId) { // The session is stored according to the room name, and the users of each room are isolated. SESSION_MAP.put(userId, session); log.info("websocket Successful connection!"); } @OnMessage public void repay(RepayReq req, Session session) { SESSION_MAP.put(req.getUserId(), session); log.info("{}Paying back:{} element", req.getName(), req.getMoneyNum()); } public void send(RepayResultRes res) throws IOException, EncodeException { if (SESSION_MAP.get(res.getUserId()) == null) { log.info("No connection found, message cannot be pushed"); return; } SESSION_MAP.get(res.getUserId()).getBasicRemote().sendObject(res); log.info("{}Successful repayment:{} Yuan, userId:{},Repayment results:{}", res.getName(), res.getMoneyNum(), res.getUserId(), res.isRepayResult()?"Also succeeded" :"failed"); } }
Here I also add a custom decoder and an encoder to parse java objects and strings from the front end, as well as a custom websocket configuration class. However, nothing has been done in this configuration class at present.
MessageDecoder.java
@Slf4j public class MessageDecoder implements Decoder.Text<RepayReq> { @Override public RepayReq decode(String s) { log.info("primal string" + s); RepayReq repayReq = null; try { repayReq = JSONObject.parseObject(s, RepayReq.class); } catch (Exception ex) { log.error(ex.getMessage()); } return repayReq; } @Override public boolean willDecode(String s) { return (s != null); } @Override public void init(EndpointConfig endpointConfig) { // do nothing. } @Override public void destroy() { // do nothing. } }
MessageEncoder.java
@Slf4j public class MessageEncoder implements Encoder.Text<RepayResultRes> { @Override public String encode(RepayResultRes object) { String s = null; try { s = JSONObject.toJSONString(object); log.info("primal: " + object.toString()); } catch (Exception ex) { log.error(ex.getMessage()); } return s; } @Override public void init(EndpointConfig endpointConfig) { // do nothing. } @Override public void destroy() { // do nothing. } }
MoneyRepayConfig.java
/** * @author Page * @date 2019-07-05 17:00 * @description */ @Slf4j public class MoneyRepayConfig extends ServerEndpointConfig.Configurator{ @Override public boolean checkOrigin(String originHeaderValue) { log.info("1=========originHeaderValue====={}", originHeaderValue); return true; } @Override public <T> T getEndpointInstance(Class<T> clazz) throws InstantiationException { log.info("2========{}========={}==",clazz, super.getEndpointInstance(clazz)); return super.getEndpointInstance(clazz); } @Override public String getNegotiatedSubprotocol(List<String> supported, List<String> requested) { log.info("3========{}====={}======{}", supported, requested, super.getNegotiatedSubprotocol(supported, requested)); return super.getNegotiatedSubprotocol(supported, requested); } @Override public List<Extension> getNegotiatedExtensions(List<Extension> installed, List<Extension> requested) { log.info("4======{}====={}======{}", installed, requested, super.getNegotiatedExtensions(installed, requested)); return super.getNegotiatedExtensions(installed, requested); } @Override public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) { log.info("5======{}======{}======{}", sec, request, response); super.modifyHandshake(sec, request, response); } }
There are several rewritable methods in ServerEndpointConfig, through which we can get the information of websocket and modify some information of connection.
3. Create WebSocketConfig
Publish websocket service through this configuration class
@Configuration @ServletComponentScan public class WebSocketConfig extends WsSci { @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } }
4. Create controller
Here I also create a controller class to simulate the response of the server and send a message to the client.
RepaySuccessController.java
/** * @author Page * @Date: 2019-07-02 10:36 * @Description: */ @Controller @RequestMapping("/money") public class RepaySuccessController { @Resource MoneyServer moneyServer; @PostMapping("/repaySuccess") public void repaySuccess(RepayResultRes req) throws IOException, EncodeException { moneyServer.send(req); } }
The project code has been put in my github warehouse, and can be downloaded if necessary.
Address: Welcome to visit
For more information about websocket, please refer to the official documents:
https://docs.oracle.com/javaee/7/api/javax/websocket/server/package-summary.html