本内容根据江南一点雨松哥的 SpringBoot 付费视频所做的学习笔记,想具体详细了解内容的,请关注微信公众号:江南一点雨。
实现单人在线聊天与之前实现聊天室的区别,在于单人在线聊天必须存在用户的概念。我们可以使用 SpringSecurity 非常方便的实现这一需求。为了方便,我们在之前的聊天室代码中进行添加功能。
- 我们需要引入 SpringSecurity 依赖,并简单配置 SecurityConfig。关于 SpringSecurity 不过多介绍。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// 在内存中添加两个用户
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("crc").password("{noop}123").roles("admin")
.and()
.withUser("一天无聊").password("{noop}123").roles("admin");
}
// 配置基本权限
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin().permitAll()
.and()
.csrf().disable();
}
}
- 在 WebSocketConfig 配置类中添加关于实现单人在线聊天的配置信息。在以下代码中主要增加两点配置信息:1.配置连接的域名(
setAllowedOrigins("http://localhost:8080")
)。2.转发的接口("/queue"
)。
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
/**
* 注册端点
* @param registry
*/
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
// 添加一个以 "/chat" 为前缀的端点,开启 SocketJS 支持
// 在新版中必须要配置连接的域:setAllowedOrigins("http://localhost:8080")
registry.addEndpoint("/chat").setAllowedOrigins("http://localhost:8080").withSockJS();
}
/**
* 配置消息代理
* @param registry
*/
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
//" /topic" 表示消息代理的前缀,消息代理将接收到消息广播给当前所有连接上来的客户端
registry.enableSimpleBroker("/topic","/queue");
}
}
- 添加一个 Chat 类,主要用来存放用户发送的信息。
public class Chat {
// 发送给谁
private String to;
// 从哪里发送的
private String from;
// 消息的内容
private String content;
@Override
public String toString() {
return "Chat{" +
"to='" + to + '\'' +
", from='" + from + '\'' +
", content='" + content + '\'' +
'}';
}
public String getTo() {
return to;
}
public void setTo(String to) {
this.to = to;
}
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
- 在 controller 层中添加访问的接口。需要通过
SimpMessagingTemplate
提供的方法进行发送。
@Autowired
SimpMessagingTemplate simpMessagingTemplate;
@MessageMapping("/online_chat")
public void chat(Principal principal, Chat chat){
// 从 security 登录信息中获取用户名,避免用户发送消息时假冒发送人
String from = principal.getName();
chat.setFrom(from);
// 第一个参数为 发送给谁,第二个参数为 前端将要监听的队列地址,第三个参数为发送的对象信息
simpMessagingTemplate.convertAndSendToUser(chat.getTo(),"/queue/chat",chat);
}
- 至此,我们后端所需要的配置都已经配置完成,只需要前端进行设计界面和发送数据到后端进行处理。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>在线单人聊天</title>
<script src="/webjars/jquery/jquery.min.js"></script>
<script src="/webjars/sockjs-client/sockjs.min.js"></script>
<script src="/webjars/stomp-websocket/stomp.min.js"></script>
</head>
<body>
<div id="chat"></div>
<div>
<label for="username">请输入目标的用户名:</label>
<input type="text" id="username" placeholder="用户名">
</div>
<div>
<label for="content">请输入聊天内容</label>
<input type="text" id="content" placeholder="聊天内容">
<input type="button" id="send" value="发送">
</div>
<script>
var stompClient;
$(function () {
connect();
$("#send").click(function () {
// 通过 stompClient.send 发送消息,第一个参数为发送的消息接口,第二个参数是优先级,第三个参数是要发送的 JSON 数据
stompClient.send("/online_chat",{},JSON.stringify({'to':$("#username").val(),'content':$("#content").val()}))
})
});
// 连接方法
function connect() {
// 获取 SockJS 连接地址,"/chat" 就是我们之前配置的注册端点
var socketjs = new SockJS("/chat");
stompClient = Stomp.over(socketjs);
// 通过 stompClient 建立连接,第一个参数不需要,第二个参数为回调函数
stompClient.connect({},function (frame) {
// 通过 stompClient.subscribe 订阅消息。"/queue/chat" 就是服务端转发的地址,但是需要手动添加 /user
stompClient.subscribe("/user/queue/chat",function (greeting) {
// 将回调函数传过来的字符串数据转成 JSON 对象,不然无法解析
var msgContent = JSON.parse(greeting.body);
// 将信息追加到 div 中
$("#chat").append("<div>" + msgContent.from + " : " + msgContent.content + "</div>")
})
});
}
</script>
</body>
</html>
需要注意的是,与之前的聊天室不同的是,前端监控订阅的消息接口需要手动添加 /user
。其次,由于是简单的小案例,在输入目标的用户名是一定要输入正确。