新建一个 websocket 模块。
工程目录。
// pom.xml
<!-- 改为 war 包 -->
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>javax.servlet</groupId>-->
<!-- <artifactId>jstl</artifactId>-->
<!-- </dependency>-->
<!-- jsp -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
</dependencies>
<!-- 使用插件启动 -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
// application.yml
server:
port: 8087
spring:
application:
name: openapi-websocket
mvc:
view:
prefix: /
suffix: .jsp
eureka:
client:
service-url:
defaultZone: http://localhost:8080/eureka/
// index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h3>消息:</h3>
<h3 id="message"></h3>
<script type="text/javascript">
var websocket = null;
if ('WebSocket' in window) {
websocket = new WebSocket("ws://localhost:8087/websocket/123");
} else {
alert("当前浏览器不支持 websocket.")
}
websocket.onerror = function () {
setMessageInnerHtml("连接错误")
}
websocket.onopen = function () {
setMessageInnerHtml("连接成功")
}
websocket.onmessage = function (event) {
console.log("进来了");
setMessageInnerHtml(event.data)
}
websocket.onclose = function () {
setMessageInnerHtml("连接关闭")
}
window.onbeforeunload = function () {
closeWebSocket();
}
function setMessageInnerHtml(message) {
var h3 = document.getElementById("message");
h3.innerHTML = message;
if ("111" == message) {
location.href = "http://www.baidu.com";
}
}
</script>
</body>
</html>
// SocketApplication.java
@SpringBootApplication
@EnableEurekaClient
public class SocketApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(SocketApplication.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(SocketApplication.class);
}
}
// MyInterceptor.java
@Component
public class MyInterceptor extends HttpSessionHandshakeInterceptor {
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
// 地址 最后的 / 后内容为会话唯一标识
String uri = request.getURI().toString();
String name = uri.substring(uri.lastIndexOf("/") + 1);
attributes.put("name", name);
System.out.println("握手之前。。name: " + name);
return super.beforeHandshake(request, response, wsHandler, attributes);
}
@Override
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, @Nullable Exception ex) {
System.out.println("握手之后。。");
super.afterHandshake(request, response, wsHandler, ex);
}
}
// MyHandler.java
@Component
public class MyHandler extends TextWebSocketHandler {
// 记录所有用户和 session 关系
private static final Map<String, WebSocketSession> allClients = new ConcurrentHashMap<>();
// 连接成功
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
// 获取拦截器中保存的 name
String name = (String) session.getAttributes().get("name");
allClients.put(name, session);
}
// 连接关闭
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
String name = (String)session.getAttributes().get("name");
allClients.remove(name);
super.afterConnectionClosed(session, status);
}
// 发送消息
public static void sendMessage(String name, String message) {
System.out.println("allClients: " + allClients);
WebSocketSession webSocketSession = allClients.get(name);
if (webSocketSession != null && webSocketSession.isOpen()) {
try {
webSocketSession.sendMessage(new TextMessage(message));
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
// WebsocketConfig.java
@Configuration
@EnableWebSocket
public class WebsocketConfig implements WebSocketConfigurer {
@Autowired
private MyHandler myHandler;
@Autowired
private MyInterceptor myInterceptor;
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) {
// //绑定拦截器,设置连接地址,及跨域访问
webSocketHandlerRegistry.addHandler(myHandler,"/websocket/*").addInterceptors(myInterceptor).setAllowedOrigins("*");
}
}
// WebsocketController.java
@RestController
@RequestMapping("/send")
public class WebsocketController {
@RequestMapping("/message/{name}")
public void message(@PathVariable("name") String name) {
System.out.println(name);
MyHandler.sendMessage(name, "接收到消息.");
}
}
// 测试。
浏览器打开 http://localhost:8087/,再另页打开 http://localhost:8087/send/message/123 。
注意。spring cloud 运行 webapp 下的 jsp 文件,需要改为 war 包,使用插件运行。