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.测试

 

原文地址:https://www.cnblogs.com/zwcry/p/9713883.html