SpringBoot + WebSocket 实现单人在线聊天

本内容根据江南一点雨松哥的 SpringBoot 付费视频所做的学习笔记,想具体详细了解内容的,请关注微信公众号:江南一点雨。

实现单人在线聊天与之前实现聊天室的区别,在于单人在线聊天必须存在用户的概念。我们可以使用 SpringSecurity 非常方便的实现这一需求。为了方便,我们在之前的聊天室代码中进行添加功能。

  1. 我们需要引入 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();
    }
}
  1. 在 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");
    }
}
  1. 添加一个 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;
    }
}
  1. 在 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);
}
  1. 至此,我们后端所需要的配置都已经配置完成,只需要前端进行设计界面和发送数据到后端进行处理。
<!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。其次,由于是简单的小案例,在输入目标的用户名是一定要输入正确。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值