后端开发 \ SpringBoot \ SpringBoot学习-(十二)SpringBoot中建立WebSocket连接

SpringBoot学习-(十二)SpringBoot中建立WebSocket连接

总点击174
简介:WebSocket握手图解: 建立连接的步骤: pom文件中添加依赖 创建握手拦截器 创建WebSocket处理类

WebSocket握手图解:

SpringBoot学习-(十二)SpringBoot中建立WebSocket连接

建立连接的步骤:

pom文件中添加依赖

创建握手拦截器

创建WebSocket处理类

配置WebSocket

前端页面访问

项目目录结构:


SpringBoot学习-(十二)SpringBoot中建立WebSocket连接

1.pom文件中添加依赖

<!-- springboot websocket -->

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-websocket</artifactId>

</dependency>

2.创建握手拦截器

用于进行握手之前和握手之后的操作


一般用于握手之前将用户信息交给WebSocketSession管理


之后可以在WebSocket处理类中获取用户信息

package com.ahut.websocket;

import java.util.Map;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.http.server.ServerHttpRequest;

import org.springframework.http.server.ServerHttpResponse;

import org.springframework.http.server.ServletServerHttpRequest;

import org.springframework.web.socket.WebSocketHandler;

import org.springframework.web.socket.server.HandshakeInterceptor;

/**

*

* @ClassName: MyWebSocketInterceptor

* @Description: 创建握手 此类用来获取登录用户信息并交由websocket管理

* @author cheng

* @date 2017年9月26日 上午10:31:30

*/

/**

* HandshakeInterceptor WebSocket握手请求的拦截器. 检查握手请求和响应,对WebSocketHandler传递属性

*/

public class MyWebSocketInterceptor implements HandshakeInterceptor {

private Logger logger = LoggerFactory.getLogger(this.getClass());

/**

* 在握手之前执行该方法,继续握手返回true,中断握手返回false. 通过attributes参数设置WebSocketSession的属性

*/

@Override

public boolean beforeHandshake(ServerHttpRequest request,ServerHttpResponse response,WebSocketHandler wsHandler,

Map<String,Object> attributes) throws Exception {

logger.info("xxx用户建立连接。。。");

if (request instanceof ServletServerHttpRequest) {

String userId = ((ServletServerHttpRequest) request).getServletRequest().getParameter("userId");

attributes.put("userId",userId);

logger.info("用户唯一标识:" + userId);

}

return true;

}

/**

* 在握手之后执行该方法. 无论是否握手成功都指明了响应状态码和相应头.

*/

@Override

public void afterHandshake(ServerHttpRequest request,

Exception exception) {

}

}

3.创建WebSocket处理类

处理类的层级关系:


SpringBoot学习-(十二)SpringBoot中建立WebSocket连接

package com.ahut.websocket;

import java.util.ArrayList;

import java.util.List;

import java.util.Map;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

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;

/**

*

* @ClassName: WebSocketPushHandler

* @Description: 创建处理器

* @author cheng

* @date 2017年9月26日 上午10:36:17

*/

public class WebSocketPushHandler extends TextWebSocketHandler {

private Logger logger = LoggerFactory.getLogger(this.getClass());

private static final List<WebSocketSession> userList = new ArrayList<>();

/**

* 用户进入系统监听

*/

@Override

public void afterConnectionEstablished(WebSocketSession session) throws Exception {

logger.info("xxx用户进入系统。。。");

logger.info("用户信息:" + session.getAttributes());

Map<String,Object> map = session.getAttributes();

for (String key : map.keySet()) {

logger.info("key:" + key + " and value:" + map.get(key));

}

userList.add(session);

}

/**

* 处理用户请求

*/

@Override

protected void handleTextMessage(WebSocketSession session,TextMessage message) throws Exception {

logger.info("系统处理xxx用户的请求信息。。。");

}

/**

* 用户退出后的处理

*/

@Override

public void afterConnectionClosed(WebSocketSession session,CloseStatus status) throws Exception {

if (session.isOpen()) {

session.close();

}

userList.remove(session);

logger.info("xxx用户退出系统。。。");

}

/**

* 自定义函数

* 给所有的在线用户发送消息

*/

public void sendMessagesToUsers(TextMessage message) {

for (WebSocketSession user : userList) {

try {

// isOpen()在线就发送

if (user.isOpen()) {

user.sendMessage(message);

}

} catch (IOException e) {

e.printStackTrace();

logger.error(e.getLocalizedMessage());

}

}

}

/**

* 自定义函数

* 发送消息给指定的在线用户

*/

public void sendMessageToUser(String userId,TextMessage message) {

for (WebSocketSession user : userList) {

if (user.getAttributes().get("userId").equals(userId)) {

try {

// isOpen()在线就发送

if (user.isOpen()) {

user.sendMessage(message);

}

} catch (IOException e) {

e.printStackTrace();

logger.error(e.getLocalizedMessage());

}

}

}

}

}

4.配置WebSocket

package com.ahut.config;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.web.socket.WebSocketHandler;

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.HandshakeInterceptor;

import com.ahut.websocket.MyWebSocketInterceptor;

import com.ahut.websocket.WebSocketPushHandler;

/**

*

* @ClassName: WebSocketConfig

* @Description: websocket配置类

* @author cheng

* @date 2017年9月26日 上午10:45:45

*/

@Configuration

@EnableWebSocket

public class WebSocketConfig implements WebSocketConfigurer {

/**

* 注册WebSocket处理类

*/

@Override

public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {

registry.addHandler(createWebSocketPushHandler(),"/webSocketServer")

.addInterceptors(createHhandshakeInterceptor()).setAllowedOrigins("*");

registry.addHandler(createWebSocketPushHandler(),"/sockjs/webSocketServer")

.addInterceptors(createHhandshakeInterceptor()).withSockJS();

}

/**

*

* @Title: createHhandshakeInterceptor

* @Description: 握手拦截器

* @return

*/

@Bean

public HandshakeInterceptor createHhandshakeInterceptor() {

return new MyWebSocketInterceptor();

}

/**

*

* @Title: createWebSocketPushHandler

* @Description: 处理类

* @return

*/

@Bean

public WebSocketHandler createWebSocketPushHandler() {

return new WebSocketPushHandler();

}

}

5.前端页面访问

<!DOCTYPE html>

<html>

<head>

<title>Java后端WebSocket的Tomcat实现</title>

</head>

<body>

Welcome<br/><input id="text" type="text"/>

<button onclick="send()">发送消息</button>

<hr/>

<button onclick="closeWebSocket()">关闭WebSocket连接</button>

<hr/>

<div id="message"></div>

</body>

<script type="text/javascript">

var websocket = null;

//判断当前浏览器是否支持WebSocket

if ('WebSocket' in window) {

websocket = new WebSocket("ws://localhost:8080/webSocketServer?userId=wrwefesdfwetrwe324324");

}

else {

alert('当前浏览器 Not support websocket')

}

//连接发生错误的回调方法

websocket.onerror = function () {

setMessageInnerHTML("WebSocket连接发生错误");

};

//连接成功建立的回调方法

websocket.onopen = function () {

setMessageInnerHTML("WebSocket连接成功");

}

//接收到消息的回调方法

websocket.onmessage = function (event) {

setMessageInnerHTML(event.data);

}

//连接关闭的回调方法

websocket.onclose = function () {

setMessageInnerHTML("WebSocket连接关闭");

}

//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。

window.onbeforeunload = function () {

closeWebSocket();

}

//将消息显示在网页上

function setMessageInnerHTML(innerHTML) {

document.getElementById('message').innerHTML += innerHTML + '<br/>';

}

//关闭WebSocket连接

function closeWebSocket() {

websocket.close();

}

//发送消息

function send() {

var message = document.getElementById('text').value;

websocket.send(message);

}

</script>

</html>

打开页面后台日志打印结果:

SpringBoot学习-(十二)SpringBoot中建立WebSocket连接

意见反馈 常见问题 官方微信 返回顶部