This article is intended as personal notes only, and most of the code is quoted from other people's articles.
springboot project in the use of websocket to do push, although quite simple, but the beginner also stepped on a few potholes, here to record.
There are two ways to use websocket: 1 is to use sockjs, 2 is to use the h5 standard. The use of Html5 standard is naturally more convenient and simple, so the record is with the use of h5.
1、pom
The core is the @ServerEndpoint annotation. This annotation is a Javaee standard in the annotation , tomcat7 above has been implemented , if the traditional method of using tomcat release project , as long as the introduction of javaee standard in the pom file can be used.
<dependency> <groupId>javax</groupId> <artifactId>javaee-api</artifactId> <version>7.0</version> <scope>provided</scope> </dependency>
However, when using springboot's built-in tomcat, there is no need to introduce javaee-api, spring-boot is already included. To use springboot's websocket functionality first introduce the springboot component.
<dependency> <groupId></groupId> <artifactId>spring-boot-starter-websocket</artifactId> <version>1.3.</version> </dependency>
By the way, springboot's advanced components automatically reference the base components, like spring-boot-starter-websocket introduces spring-boot-starter-web and spring-boot-starter, so don't reintroduce them.
2. Use @ServerEndpoint to create a websocket endpoint.
The first step is to inject the ServerEndpointExporter, a bean that automatically registers the websocket endpoint declared using the @ServerEndpoint annotation. note that if you are using a standalone servlet container, rather than springboot's built-in containers directly, you should not inject the ServerEndpointExporter, as it will be provided and managed by the container itself.
@Configuration public class WebSocketConfig { @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } }
The next step is to write a specific implementation of websocket class, it is very simple, directly on the code:
@ServerEndpoint(value = "/websocket") @Component public class MyWebSocket { // Static variable to keep track of the current number of online connections. It should be designed to be thread-safe. private static int onlineCount = 0; // Thread-safe Set of the concurrent package to hold the corresponding MyWebSocket object for each client. private static CopyOnWriteArraySet<MyWebSocket> webSocketSet = new CopyOnWriteArraySet<MyWebSocket>(); //Connection session with a client through which data needs to be sent to the client private Session session; /** * :: Methods invoked when the connection is successfully established */ @OnOpen public void onOpen(Session session) { = session; (this); // Add to set addOnlineCount(); //Online plus 1 ("A new connection has been added! The current number of people online is " + getOnlineCount()); try { sendMessage(CommonConstant.CURRENT_WANGING_NUMBER.toString()); } catch (IOException e) { ("IO anomaly."); } } /** * Methods called by connection closure */ @OnClose public void onClose() { (this); //delete from set subOnlineCount(); //Online minus 1 ("One connection closed! The current number of people online is " + getOnlineCount()); } /** * Methods called upon receipt of a client message * * @param message Message sent by the client */ @OnMessage public void onMessage(String message, Session session) { ("Message from client:" + message); //Mass message for (MyWebSocket item : webSocketSet) { try { (message); } catch (IOException e) { (); } } } /** * Called on an error @OnError public void onError(Session session, Throwable error) { ("An error has occurred."); (); } public void sendMessage(String message) throws IOException { ().sendText(message); //().sendText(message); } /** * Mass customized messages * */ public static void sendInfo(String message) throws IOException { for (MyWebSocket item : webSocketSet) { try { (message); } catch (IOException e) { continue; } } } public static synchronized int getOnlineCount() { return onlineCount; } public static synchronized void addOnlineCount() { ++; } public static synchronized void subOnlineCount() { --; } }
The only difference between using springboot is that you have to @Component declare it, while using a standalone container is managed by the container itself for websockets, but in springboot even the container is managed by spring.
Although @Component is singleton by default, springboot still initializes a bean for each websocket connection, so it can be saved with a static set.
3. Front-end code
<!DOCTYPE HTML> <html> <head> <title>My WebSocket</title> </head> <body> Welcome<br/> <input id="text" type="text" /><button onclick="send()">Send</button> <button onclick="closeWebSocket()">Close</button> <div id="message"> </div> </body> <script type="text/javascript"> var websocket = null; // Determine whether the current browser supports WebSocket. if('WebSocket' in window){ websocket = new WebSocket("ws://localhost:8084/websocket"); } else{ alert('Not support websocket') } // Callback method if a connection error occurs = function(){ setMessageInnerHTML("error"); }; // Callback method for successful connection establishment = function(event){ setMessageInnerHTML("open"); } // Callback methods for received messages = function(event){ setMessageInnerHTML(); } // Connection closure callback method = function(){ setMessageInnerHTML("close"); } // Listen to the window close event, when the window is closed, take the initiative to close the websocket connection, to prevent the connection has not been disconnected before closing the window, the server side will throw an exception. = function(){ (); } // Display the message on the web page function setMessageInnerHTML(innerHTML){ ('message').innerHTML += innerHTML + '<br/>'; } // Close the connection function closeWebSocket(){ (); } //Send a message function send(){ var message = ('text').value; (message); } </script> </html>
4. Summary
springboot has done a deep integration and optimization, be careful whether to add unwanted dependencies, configurations or declarations. As many of the articles explaining the use of components are integrated with spring, there will be some configuration, when using springboot, because springboot already has its own configuration, and then these configurations may lead to a variety of exceptions.
This is the whole content of this article.