Springboot WebSocket例子
Springboot整合WebSocket
1.application.properties
#设置服务端口号 server.port=8080 #thymeleaf配置 #是否启用模板缓存。 spring.thymeleaf.cache=false #是否为Web框架启用Thymeleaf视图解析。 spring.thymeleaf.enabled=true #在SpringEL表达式中启用SpringEL编译器。 spring.thymeleaf.enable-spring-el-compiler=true #模板文件编码。 spring.thymeleaf.encoding=UTF-8 #要应用于模板的模板模式。另请参见Thymeleaf的TemplateMode枚举。 spring.thymeleaf.mode=HTML5 #在构建URL时添加前缀以查看名称的前缀。 spring.thymeleaf.prefix=classpath:/templates/ #Content-Type写入HTTP响应的值。 spring.thymeleaf.servlet.content-type=text/html #在构建URL时附加到视图名称的后缀。 spring.thymeleaf.suffix=.html
2.pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.szw.learn</groupId> <artifactId>websocket_01</artifactId> <version>0.0.1-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.16.RELEASE</version> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <maven.test.skip>true</maven.test.skip> <skipTests>true</skipTests> <start-class>com.szw.learn.Websocket01Application</start-class> </properties> <dependencies> <!-- 使用web启动器 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 测试 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- 模板引擎 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <!-- websocket --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> </dependencies> <repositories> <repository> <id>nexus-aliyun</id> <name>Nexus aliyun</name> <url>http://maven.aliyun.com/nexus/content/groups/public</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>nexus-aliyun</id> <name>Nexus aliyun</name> <url>http://maven.aliyun.com/nexus/content/groups/public</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </pluginRepository> </pluginRepositories> <build> <plugins> <!-- 要将源码放上去,需要加入这个插件 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> <configuration> <attach>true</attach> </configuration> <executions> <execution> <phase>compile</phase> <goals> <goal>jar</goal> </goals> </execution> </executions> </plugin> <!-- 打包 --> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <fork>true</fork> </configuration> </plugin> </plugins> </build> </project>
3.ServerEndpointExporter注册
package com.szw.learn.websocket; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.server.standard.ServerEndpointExporter; @Configuration public class WebsocketConfig { /** * <br>描 述: @Endpoint注解的websocket交给ServerEndpointExporter自动注册管理 * @return */ @Bean public ServerEndpointExporter serverEndpointExporter(){ return new ServerEndpointExporter(); } }
4.WebsocketEndpoint长连接端点
package com.szw.learn.websocket; import java.io.IOException; import java.util.concurrent.CopyOnWriteArraySet; import javax.websocket.OnClose; import javax.websocket.OnError; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; import org.springframework.stereotype.Component; /** *@ServerEndpoint(value="/websocket")value值必须以/开路 *备注:@ServerEndpoint注解类不支持使用@Autowire */ @Component @ServerEndpoint(value="/websocket") public class WebsocketEndpoint { //存放该服务器该ws的所有连接。用处:比如向所有连接该ws的用户发送通知消息。 private static CopyOnWriteArraySet<WebsocketEndpoint> sessions = new CopyOnWriteArraySet<>(); private Session session; @OnOpen public void onOpen(Session session){ System.out.println("java websocket:打开连接"); this.session = session; sessions.add(this); } @OnClose public void onClose(Session session){ System.out.println("java websocket:关闭连接"); sessions.remove(this); } @OnMessage public void onMessage(Session session,String message) throws IOException{ System.out.println("java websocket 收到消息:"+message); session.getBasicRemote().sendText("后台接收到您发的消息:"+message); } @OnError public void onError(Session session,Throwable error){ System.out.println("java websocket 出现错误"); } public Session getSession() { return session; } public void setSession(Session session) { this.session = session; } }
5.index.html用户端
<!doctype html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="utf-8"></meta> <title>websocket</title> </head> <body> hello websocket<br/> <input id="input_id" type="text" /><button onclick="sendMessage()">发送</button> <button onclick="closeWebsocket()">关闭</button> <div id="message_id"></div> </body> <script type="text/javascript"> document.getElementById('input_id').focus(); var websocket = null; //当前浏览前是否支持websocket if("WebSocket" in window){ var url = "ws://127.0.0.1:8080/websocket"; websocket = new WebSocket(url); }else{ alert("浏览器不支持websocket"); } websocket.onopen = function(event){ setMessage("打开连接"); } websocket.onclose = function(event){ setMessage("关闭连接"); } websocket.onmessage = function(event){ setMessage(event.data); } websocket.onerror = function(event){ setMessage("连接异常"); } //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。 window.onbeforeunload = function(){ closeWebsocket(); } //关闭websocket function closeWebsocket(){ //3代表已经关闭 if(3!=websocket.readyState){ websocket.close(); }else{ alert("websocket之前已经关闭"); } } //将消息显示在网页上 function setMessage(message){ document.getElementById('message_id').innerHTML += message + '<br/>'; } //发送消息 function sendMessage(){ //1代表正在连接 if(1==websocket.readyState){ var message = document.getElementById('input_id').value; setMessage(message); websocket.send(message); }else{ alert("websocket未连接"); } document.getElementById('input_id').value=""; document.getElementById('input_id').focus(); } </script> </html>
6.WebsocketController测试地址
package com.szw.learn.websocket; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; @RequestMapping("websocket") @Controller public class WebsocketController { private static final String INDEX = "websocket/index"; @RequestMapping("index") public ModelAndView index(){ return new ModelAndView(INDEX); } }
7.Websocket01Application启动类
package com.szw.learn; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Websocket01Application { public static void main(String[] args) { System.setProperty("spring.devtools.restart.enabled", "false"); SpringApplication.run(Websocket01Application.class, args); } }
8.测试