How Grails support WebSocket?

Log practice

  1. Server development

    1.1 The introduction of package

     	implementation "org.grails.plugins:grails-spring-websocket:2.5.0.RC1"
    

    1.2. Writing a controller, designated by annotation on the method out of the target address . TODO] [
    1.3. Open the safe limit / stomp / ** of

  2. JS Client write the code [TODO]

  3. Write Java Client Code [TODO]

About WebSocket

  • Introduction websock the basic concepts and development of technology; This blog describes the more technical details, such as data frames, API.

  • grails 有 websocket plugin

  • WebSocket protocol , this probably need to see it again

    • Which is described on the "reconnect" to resolve my doubts. See 7.2.3. Recovering from Abnormal Closure
      first WebSocket itself is no such thing as automatic reconnection, the reconnection must be made by the client to achieve their own, reconnection time interval is very important to avoid the same time instant reconnection, resulting in DoS attacks. Strategy is randomly selected in accordance with a number of retries exponentially as the time interval 2, and an upper limit, the time interval from the beginning after arrival, the first reconnection takes a random time between 0-5 seconds more it is good.
  • spring websocket regarding the usage

  • websocket 的 java client libarary

    • Groovy for vert.x , can be used to achieve websocket client. But the whole programming mode are changed to adapt to slow up, so I chose the realization of Spring is still family. Spring is indeed trustworthy []

Problems encountered

After the code is written in accordance with the plurality of sample, the following various problems occurred, but eventually solved one by one.

java.lang.NoClassDefFoundError: javax/websocket/ClientEndpointConfig$Configurator from StandardWebsocketClient

Or tyros need to add a spring-boot-websocket-starter pack.
Final selection of the spring-boot-websocket-starter package.

The HTTP response from the server [200] did not permit the HTTP upgrade to WebSocket

org.glassfish.tyrus.core.HandshakeException: Response code was not 101: 200.

Switch to SockJSClient plus Websocket resolved Transport.

The subject can not receive the message sent by subscription

You can send to the server, but can not receive the message server.
The original is Jackson2MessageConverter does not support MIMIE Message header returned by the server that Content-Type.

contentType -> {MimeType@2934} "text/plain;charset=UTF-8"

This should be application / json it before going process. We need to force told converter support this MIME type.

// 让 converter 支持 text/plain MIME 类型,否则 handler 收不到通知
stompClient.setMessageConverter(new MappingJackson2MessageConverter(
        new MimeType("application", "json"),
        new MimeType("text", "plain")));

CONNECT message needs to get to know the difference between 200 and 101 return

StandardWebSocketClient started with a direct connection to the client class server, connect the results of the function reports an error:

The HTTP response from the server [200] did not permit the HTTP upgrade to WebSocket

What does this mean in the end? This exception is thrown if it does not establish a TCP connection to the real? Or WebSocket itself does not create additional new TCP connection?

Websocket basic principle is:

In the connection establishment phase, or even using the HTTP protocol port to establish a TCP / IP connection, and then discard the original HTTP protocol on the link, and use WebSocket protocol for full duplex communication. So in fact equivalent to a WebSocket connection a HTTP connection, like a long HTTP connection, communication protocol except (wire-format) different from HTTP.

The conclusion is that, WebSocket will not establish an additional TCP connection, and will initiate a connection with the HTTP request where the link as WebSocket link.

On the establishment of the connection, the server returns a status code Grails is 101 rather than 200, such as impact written specification:

The handshake from the server is much simpler than the client
handshake.  The first line is an HTTP Status-Line, with the status
code 101:

     HTTP/1.1 101 Switching Protocols

Any status code other than 101 indicates that the WebSocket handshake
has not completed and that the semantics of HTTP still apply.  The
headers follow the status code.

That follow-up also need to use the HTTP protocol instead of WebSocket protocol.

Because SpringWebSocket use something called SockJs, the main role of this SockJs is that it gives no WebSocket WebSocket interface runs on supported browsers, JS to achieve using conventional techniques and HTTP requests. These technologies have the WebSocket, XHR / Ajax, iframe page. [Are compatible browser to blame]

Check SockJsClient code, I found it and InfoReceiver and RestTemplateXhrTransport related.

InfoReceiver is SockJS to perform Info a component requests agreement, it queries the server, in order to understand the ability of the server endpoint, such as whether to support WebSocket. That SockJS can also be implemented WebSocket server side does not provide the ability, but the client can still use analog WebSocket interface. [Feeling another successful framework for the world to engage in complex]

It would appear that it is necessary to look at the agreement SockJS ah. I found in here .

The basic concepts are:

  • Service - a server can provide multiple services, each service has a base_url.
  • Base URL - to the URL address of the client, is the prefix for all other derivative requested URL, can not "/" end, ashttp://localhost:8000/echo
  • / Info - this URL (of course, is based on the base url) can be accessed by the client before the start of session. Used to query the server supports websocket, measuring network roundtrip time (travel time).
  • Direct access SockJS websocket server port should fail. Yes it is [a]
  • Top session URL: / <server> / <session> - session (the session is a connection) is always initiated by the client.
  • Protocol and framing - protocol and framing, SockJS WebSocket consistent only with the API, but different network-layer protocols.
  • WebSocket protocols: / * / * / websocket - SockJS most important feature is support for native WebSocket protocol, a good SockJS server must support at least four WebSocket protocol variants, namely Chrome, Safari and Firefox.

After reading SockJS agreement, understand SockJS just borrowed the WebSocket API, Neri has done a lot to expand and enhance the aim of better let the browser and the server in a unified WebSocket API to communicate.

The Spring-WebSocket specification is based on SockJS, so that we have been fooled, in fact, Spring-WebSocket using SockJS specification, although the WebSocket API is.

So the answer to this problem is to use native WebSocket protocol client connection to the Spring WebSocket server (grails-websocket-plugin is developed based on Spring-WebSocket) exception reports, the correct behavior is defined by a SockJS end StandardWebSocketClient.

We must use SockJS to access SockJS server, so everything is right.
[Thanks to SockJS, make so complicated technology world has been a glimmer of coordination]

Reference material

  1. grails-spring-websocket-plugin doc
  2. spring websocket sample project
  3. websockets-api-java-spring- client Client Examples
  4. websocket alternative implementations sockjs the Spring also provides a backup plan sockjs, good. Because there is no automatic reconnection SockJS function, it is necessary to use this sockjs-reconnect to do.
  5. Examples of the use of the spring scheduler in grails
Published 46 original articles · won praise 7 · views 80000 +

Guess you like

Origin blog.csdn.net/yangbo_hr/article/details/104544608