SpringBoot中怎么利用WebSocket实现即时消息

今天就跟大家聊聊有关SpringBoot中怎么利用WebSocket实现即时消息,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。

成都创新互联从2013年创立,是专业互联网技术服务公司,拥有项目网站建设、网站制作网站策划,项目实施与项目整合能力。我们以让每一个梦想脱颖而出为使命,1280元湘乡做网站,已为上家服务,为湘乡各地企业和个人服务,联系电话:028-86922220

依赖

         org.springframework.boot         spring-boot-starter-web           org.springframework.boot         spring-boot-starter-websocket 

定义消息类型

抽象消息对象

public class AbstractMessage {     /**      *  消息类型      */     protected String type ;          /**      *  消息内容      */     protected String content ;     /**      *  消息日期      */     protected String date ; }

消息对象子类

1、Ping检查消息

public class PingMessage extends AbstractMessage {     public PingMessage() {}     public PingMessage(String type) {         this.type = type ;     } }

2、系统消息

public class SystemMessage extends AbstractMessage {     public SystemMessage() {}     public SystemMessage(String type, String content) {         this.type = type ;         this.content = content ;     } }

3、点对点消息

public class PersonMessage extends AbstractMessage {     private String fromName ;     private String toName ; }

消息类型定义

public enum MessageType {          /**      *  系统消息 0000;心跳检查消息 0001;点对点消息2001      */     SYSTEM("0000"), PING("0001"), PERSON("2001") ;          private String type ;          private MessageType(String type) {         this.type = type ;     }      public String getType() {         return type;     }      public void setType(String type) {         this.type = type;     }      }

 WebSocket服务端点

该类作用就是定义客户端连接的地址

@ServerEndpoint(value = "/message/{username}",      encoders = {WsMessageEncoder.class},     decoders = {WsMessageDecoder.class},     subprotocols = {"gmsg"},     configurator = MessageConfigurator.class)   @Component   public class GMessageListener {          public static ConcurrentMap sessions = new ConcurrentHashMap<>();     private static Logger logger = LoggerFactory.getLogger(GMessageListener.class) ;        private String username ;          @OnOpen       public void onOpen(Session session, EndpointConfig config, @PathParam("username") String username){         UserSession userSession = new UserSession(session.getId(), username, session) ;         this.username = username ;         sessions.put(username, userSession) ;         logger.info("【{}】用户进入, 当前连接数:{}", username, sessions.size()) ;      }          @OnClose       public void onClose(Session session, CloseReason reason){           UserSession userSession = sessions.remove(this.username) ;         if (userSession != null) {             logger.info("用户【{}】, 断开连接, 当前连接数:{}", username, sessions.size()) ;         }     }          @OnMessage     public void pongMessage(Session session, PongMessage message) {         ByteBuffer buffer = message.getApplicationData() ;         logger.debug("接受到Pong帧【这是由浏览器发送】:" + buffer.toString());     }          @OnMessage     public void onMessage(Session session, AbstractMessage message) {         if (message instanceof PingMessage) {             logger.debug("这里是ping消息");             return ;         }         if (message instanceof PersonMessage) {             PersonMessage personMessage = (PersonMessage) message ;             if (this.username.equals(personMessage.getToName())) {                 logger.info("【{}】收到消息:{}", this.username, personMessage.getContent());             } else {                 UserSession userSession = sessions.get(personMessage.getToName()) ;                 if (userSession != null) {                     try {                         userSession.getSession().getAsyncRemote().sendText(new ObjectMapper().writeValueAsString(message)) ;                     } catch (JsonProcessingException e) {                         e.printStackTrace();                     }                 }             }             return ;         }         if (message instanceof SystemMessage) {             logger.info("接受到消息类型为【系统消息】") ;              return ;         }     }          @OnError     public void onError(Session session, Throwable error) {         logger.error(error.getMessage()) ;     } }

WsMessageEncoder.java类

该类的主要作用是,当发送的消息是对象时,该如何转换

public class WsMessageEncoder implements Encoder.Text {     private static Logger logger = LoggerFactory.getLogger(WsMessageDecoder.class) ;     @Override     public void init(EndpointConfig endpointConfig) {     }     @Override     public void destroy() {     }     @Override     public String encode(AbstractMessage tm) throws EncodeException {         String message = null ;         try {             message = new ObjectMapper().writeValueAsString(tm);         } catch (JsonProcessingException e) {             logger.error("JSON处理错误:{}", e) ;         }         return message;     } }

WsMessageDecoder.java类

该类的作用是,当接收到消息时如何转换成对象。

public class WsMessageDecoder implements  Decoder.Text {      private static Logger logger = LoggerFactory.getLogger(WsMessageDecoder.class) ;     private static Set msgTypes = new HashSet<>() ;          static {         msgTypes.add(MessageType.PING.getType()) ;         msgTypes.add(MessageType.SYSTEM.getType()) ;         msgTypes.add(MessageType.PERSON.getType()) ;     }     @Override     @SuppressWarnings("unchecked")     public AbstractMessage decode(String s) throws DecodeException {         AbstractMessage message = null ;         try {             ObjectMapper mapper = new ObjectMapper() ;             Map map = mapper.readValue(s, Map.class) ;             String type = map.get("type") ;             switch(type) {                 case "0000":                     message = mapper.readValue(s, SystemMessage.class) ;                     break;                 case "0001":                     message = mapper.readValue(s, PingMessage.class) ;                     break;                 case "2001":                     message = mapper.readValue(s, PersonMessage.class) ;                     break;             }         } catch (JsonProcessingException e) {             logger.error("JSON处理错误:{}", e) ;         }         return message ;     }      // 该方法判断消息是否可以被解码(转换)     @Override     @SuppressWarnings("unchecked")     public boolean willDecode(String s) {         Map map = new HashMap<>() ;         try {             map = new ObjectMapper().readValue(s, Map.class);         } catch (JsonProcessingException e) {             e.printStackTrace();         }         logger.debug("检查消息:【" + s + "】是否可以解码") ;         String type = map.get("type") ;         if (StringUtils.isEmpty(type) || !msgTypes.contains(type)) {             return false ;         }         return true ;     }     @Override     public void init(EndpointConfig endpointConfig) {     }     @Override     public void destroy() {     } }

MessageConfigurator.java类

该类的作用是配置服务端点,比如配置握手信息

public class MessageConfigurator extends ServerEndpointConfig.Configurator {     private static Logger logger = LoggerFactory.getLogger(MessageConfigurator.class) ;     @Override     public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {         logger.debug("握手请求头信息:" + request.getHeaders());         logger.debug("握手响应头信息:" + response.getHeaders());         super.modifyHandshake(sec, request, response);     }    }

WebSocke配置类

@Configuration public class WebSocketConfig {          @Bean     public ServerEndpointExporter serverEndpointExporter (){           return new ServerEndpointExporter();       }        }

当以jar包形式运行时需要配置该bean,暴露我们配置的@ServerEndpoint;当我们以war独立tomcat运行时不能配置该bean。

前端页面

                     WebSocket                           进入     
     
              当前用户:
         用户:

         内容:
         发送     
     
                       
   

到此所有的代码完毕,接下来测试

测试

打开两个标签页,以不同的用户进入。

SpringBoot中怎么利用WebSocket实现即时消息

SpringBoot中怎么利用WebSocket实现即时消息

输入对方用户名发送消息

SpringBoot中怎么利用WebSocket实现即时消息

SpringBoot中怎么利用WebSocket实现即时消息

看完上述内容,你们对SpringBoot中怎么利用WebSocket实现即时消息有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注创新互联行业资讯频道,感谢大家的支持。


分享名称:SpringBoot中怎么利用WebSocket实现即时消息
当前链接:http://csdahua.cn/article/ijcocc.html
扫二维码与项目经理沟通

我们在微信上24小时期待你的声音

解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流