spring WebSocket example details

  • 2020-06-01 09:47:25
  • OfStack

scenario

As one of the new features of Html5, websocket aims to establish a full-duplex communication mode between the browser and the server, so as to solve the excessive resource consumption caused by the request-response of http. At the same time, it provides a brand new implementation method for the application of special scenes, such as chat, stock trading, games and other industries requiring high real-time performance.

background

In the browser, http can only realize one-way communication. comet can simulate two-way communication to a certain extent, but it is inefficient and requires good support from the server. flash socket and xmlsocket can realize the real two-way communication, through flex ajax bridge, can use these two functions in javascript. Predictably, if websocket1 been implemented in the browser, will replace the above two technologies, has been widely used. In the face of this situation, defines WebSocket HTML5 agreement, can better conserve server resources and bandwidth and achieve real-time communication. All major browsers now support websocket, while IE requires IE10+

1. POM dependency

POM dependencies, spring4.1.4.RELEASE, spring core dependencies, please add your own, the following is websocket related jar


<dependency>
  <groupId>javax.websocket</groupId>
  <artifactId>javax.websocket-api</artifactId>
  <version>1.0</version>
  <scope>provided</scope>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-websocket</artifactId>
  <version>4.1.4.RELEASE</version>
</dependency>

2. WebSocket entrance


@Configuration
@EnableWebMvc
@EnableWebSocket
public class WebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer {
  @Override
  public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
    // A domain that allows connections , Only in http or https At the beginning 
    String[] allowsOrigins = {"http://www.xxx.com"};
    
    //WebIM WebSocket channel 
    registry.addHandler(chatWebSocketHandler(),"/      webSocketIMServer").setAllowedOrigins(allowsOrigins).addInterceptors(myInterceptor());
    registry.addHandler(chatWebSocketHandler(), "/sockjs/w     ebSocketIMServer").setAllowedOrigins(allowsOrigins).addInterceptors(myInterceptor()).withSockJS();
  }
  @Bean
  public ChatWebSocketHandler chatWebSocketHandler() {
    return new ChatWebSocketHandler();
  }
  @Bean
  public WebSocketHandshakeInterceptor myInterceptor(){
    return new WebSocketHandshakeInterceptor();
  }
}

1. Implement WebSocketConfigurer interface, override registerWebSocketHandlers method, which is a core implementation method, configure websocket entry, allow access to the domain, register Handler, SockJs support and interceptor.

2. registry.addHandler registration and routing function, when the client initiates the websocket connection, and transfers /path to the corresponding handler for processing, without realizing the specific business logic, it can be understood as a collection and task distribution center.

3.setAllowedOrigins(String[] domains), allows long connection between the specified domain name or IP(including port number). If only your own domain name is allowed, you can set it up here easily. If you use the "*" number for unlimited time, if you specify a domain name, you must start with http or https.

4.addInterceptors, as the name implies, is to add an interceptor to handler. We can add our own logic code before and after calling handler.

5.spring websocket also supports the STOMP protocol and will share it next time.

3. Interceptor implementation


public class WebSocketHandshakeInterceptor implements HandshakeInterceptor {

  @Override
  public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object
        > attributes) throws Exception {
    if (request instanceof ServletServerHttpRequest) {
      attributes.put("username",userName);
    }
    return true;
  }

  @Override
  public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {

  }
}

beforeHandshake, before calling the handler preprocessing method. It is commonly used to register user information, bind WebSocketSession, and get WebSocketSession messages according to user information in handler.

4. Handler processing class


public class ChatWebSocketHandler extends TextWebSocketHandler{
  
  private final static List<WebSocketSession> sessions = Collections.synchronizedList(new ArrayList<WebSocketSession>());
  // Receive the text message and send it 
  @Override
  protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
    chatTextMessageHandler(message.getPayload());
    super.handleTextMessage(session, message);
  }
  // Connection setup post-processing 
  @SuppressWarnings("unchecked")
  @Override
  public void afterConnectionEstablished(WebSocketSession session) throws Exception {
    logger.debug("connect to the websocket chat success......");
    sessions.add(session);
    // Processing offline messages 
  }
  // Handled when an exception is thrown 
  @Override
  public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
    if(session.isOpen()){
      session.close();
    }
    logger.debug("websocket chat connection closed......");
    sessions.remove(session);
  }
  // Connection closing post processing 
  @Override
  public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
    logger.debug("websocket chat connection closed......");
    sessions.remove(session);
  }

  @Override
  public boolean supportsPartialMessages() {
    return false;
  }
}

5. Client connection


var host = window.location.host;
var websocket;
if ('WebSocket' in window) {
  websocket = new ReconnectingWebSocket("ws://"
    + host + "/webSocketIMServer", null, {debug:true, maxReconnectAttempts:4});
} else if ('MozWebSocket' in window) {
  websocket = new MozWebSocket("ws://" + host
    + "/webSocketIMServer");
} else {
  websocket = new SockJS("http://" + host
      + "/sockjs/webSocketIMServer");
}
websocket.onopen = function(evnt) {
  console.log("websocket Connected to the ");
};
websocket.onmessage = function(evnt) {
  messageHandler(evnt.data);
};
websocket.onerror = function(evnt) {
  console.log("websocket error ");
};
websocket.onclose = function(evnt) {
  console.log("websocket Shut down ");
}

ReconnectingWebSocket is used here.js adds extensions to the browser's own websocket, such as reconnection, connection timeout, failed reconnection interval, maximum number of connection attempts, etc.


Related articles: