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>springws</groupId>
<artifactId>springws</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.3.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<!----- 數據庫操做的相關依賴 ----->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.properties
server.port=8080
########################################################
###THYMELEAF (ThymeleafAutoConfiguration)
########################################################
#spring.thymeleaf.prefix=classpath:/templates/
#spring.thymeleaf.suffix=.html
#spring.thymeleaf.mode=HTML5
#spring.thymeleaf.encoding=UTF-8
# ;charset=<encoding> is added
# spring.thymeleaf.content-type=text/html
# set to false for hot refresh
spring.thymeleaf.cache=false
debug=true
##########
#spring.datasource.url=jdbc:mysql://localhost:3306/ccvms
#spring.datasource.username=root
#spring.datasource.password=root
#spring.datasource.driver-class-name=com.mysql.jdbc.Driver
#spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
#spring.jpa.hibernate.ddl-auto=none
#spring.jpa.show-sql=true
#spring.jackson.serialization.indent-output=true
建立 config
package com.ws.util;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Bean
public ServerEndpointExporter serverEndpointExporter(ApplicationContext context) {
return new ServerEndpointExporter();
}
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(new CountWebSocketHandler(), "/web/count.do").addInterceptors(new HandshakeInterceptor());
}
}
建立攔截器
package com.ws.util;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;
import java.util.Map;
public class HandshakeInterceptor extends HttpSessionHandshakeInterceptor {
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
Map<String, Object> attributes) throws Exception {
//解決The extension [x-webkit-deflate-frame] is not supported問題
if (request.getHeaders().containsKey("Sec-WebSocket-Extensions")) {
request.getHeaders().set("Sec-WebSocket-Extensions", "permessage-deflate");
}
System.out.println("Before Handshake");
return super.beforeHandshake(request, response, wsHandler, attributes);
}
@Override
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
Exception ex) {
System.out.println("After Handshake");
super.afterHandshake(request, response, wsHandler, ex);
}
}
建立處理器
package com.ws.util;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import java.io.IOException;
import java.util.*;
@Component
public class CountWebSocketHandler extends TextWebSocketHandler {
private static Map<String,WebSocketSession> sessionMap = new HashMap<>();
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
// session.sendMessage(new TextMessage(session.getPrincipal().getName()+",你是第" + (sessionMap.size()) + "位訪客")); //p2p
if(message.getPayload().equals("ping")) {
sendMessage(session.getId(),"pong"+session.getId());
return;
}else {
//處理正常的對話
}
}
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
sessionMap.put(session.getId(),session);
sendMessage(session.getId(), "welcome to connect");
super.afterConnectionEstablished(session);
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
sessionMap.remove(session.getId());
super.afterConnectionClosed(session, status);
}
/**
* 發送消息
* 單發
*/
public static void sendMessage(String username,String message) throws IOException {
sendMessage(Arrays.asList(username),Arrays.asList(message));
}
/**
*
* 發送消息
* 羣發
*/
public static void sendMessage(Collection<String> acceptorList,String message) throws IOException {
sendMessage(acceptorList,Arrays.asList(message));
}
/**
* 發送消息,p2p 羣發都支持
*/
public static void sendMessage(Collection<String> acceptorList, Collection<String> msgList) throws IOException {
if (acceptorList != null && msgList != null) {
for (String acceptor : acceptorList) {
WebSocketSession session = sessionMap.get(acceptor);
if (session != null && session.isOpen() ) {
for (String msg : msgList) {
session.sendMessage(new TextMessage(msg.getBytes()));
}
}
}
}
}
/**
羣發/推送
**/
public static void sendToAll() throws IOException {
sendMessage(sessionMap.keySet(), " this is from web ");
}
}
啓動類
package com.ws;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class App {
public static void main(String ... args){
SpringApplication.run(App.class,args);
}
}
html測試
打開console查看
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
</body>
<script>
var url = 'ws://localhost:8080/web/count.do';
var ws = new WebSocket(url);
ws.onopen = function(e)
{
ws.send('hello');
setInterval(function(){
ws.send('ping')
},10000)
};
ws.onmessage = function(e) {
console.log(e.data);
};
ws.onerror = function(e) {
console.log(e)
};
</script>
</html>
服務器端推送
package com.ws.controller;
import java.io.IOException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ws.util.CountWebSocketHandler;
@RestController
public class IndexController {
@GetMapping("/push")
public String index() throws IOException{
CountWebSocketHandler.sendToAll();
return "success";
}
}