(二十六)Spring Boot 整合 WebSocket【点对点消息】

      在 Spring Boot 中, SimpMessagingTemplate 已经配置好,开发者直接注入进来即可。使用 SimpMessagingTemplate ,开发者可以在任意地方发送消息到 broker ,也可以发送消息给某一个用户,这就是点对点的消息发送。

1、创建项目,添加依赖

<!--Web Socket 依赖-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>webjars-locator-core</artifactId>
</dependency>

<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>sockjs-client</artifactId>
    <version>1.1.2</version>
</dependency>

<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>stomp-websocket</artifactId>
    <version>2.3.3</version>
</dependency>

<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>jquery</artifactId>
    <version>3.3.1</version>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

2、配置 Spring Security

import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;


@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {


    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    /**
     * 功能描述:在该方法中配直两个用户,一个用户名是 admin ,密码是 123456,具备两个角色 ADMIN 和 USER,另一个用户名是 wi-gang ,密码是 123456 ,具备一个角色 USER
     * @author wi-gang
     * @date 2022/1/23 11:28 下午
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("admin").password("$2a$10$RMuFXGQ5AtH4wOvkUqyvuecpqUSeoxZYqilXzbz50dceRsga.WYiq").roles("ADMIN")
                .and()
                .withUser("wi-gang").password("$2a$10$RMuFXGQ5AtH4wOvkUqyvuecpqUSeoxZYqilXzbz50dceRsga.WYiq").roles("USER");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .anyRequest()
                .authenticated()
                .and()
                .formLogin()
                .permitAll();
    }
}

3、配置 WebSocketConfig

import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;

/**
 * 功能描述:自定义类配置 WebSocket
 * @author wi-gang
 * @date 2022/2/10 11:01 上午
 */

@Configuration
//开启 WebSocket 消息代理
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {


    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        //定义一个前缀为"/chat"的 endpoint,并开启sockjs支持
        //sockjs可以解决浏览器对 WebSocket 的兼容性问题,客户端通过这里配置的URL来建立 WebSocket 连接
        registry.addEndpoint("/chat").withSockJS();
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        //设置消息代理的前缀,即如果消息的前缀是"/topic",就会将消息转发给消息代理(broker),再由消息代理将消息广播给当前连接的客户端。在方法的基础上又增加了 broker 前缀 "/queue",方便对群发消息和点对点消息进行管理。
        registry.enableSimpleBroker("/topic","/queue");
        //配置一个或者多个前缀,通过这些前缀过滤出需要被注解方法处理的消息
        //例如:前缀为"/app"的 destination 可以通过@MessageMapping注解的方法处理,而其他destination(例如"topic","/queue")将被直接交给broker处理。
        registry.setApplicationDestinationPrefixes("/app");
    }
}

4、配置controller

@RestController
public class TestController {

    @Autowired
    private SimpMessagingTemplate simpMessagingTemplate;

    @MessageMapping("/chat")
    public void chat(Principal principal, Chat chat) {
        String from = principal.getName();
        chat.setFrom(from);
        simpMessagingTemplate.convertAndSendToUser(chat.getTo(), "/queue/chat", chat);

    }
}
class Chat {
    private String to;
    private String from;
    private String content;
	//省略get/set方法
}

代码解释:

  • @MessageMapping("/chat") 表示来自/app/chat路径的消息将被 chat 方法处理。chat 方法的第一个参数 Principal 可以用来获取当前登录用户的信息,第二个参数则是客户端发送来的消息。
  • 在 chat 方法中首先获取当前用户的用户名, 设置给 chat 对象的 from 属性,再将消息发送出去,发送的目标用户就是 chat 对象的 to 属性值。

5、创建在线聊天页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>单聊</title>
    <!--引入外部的 JS 库,这些 JS 库在 pom.xml 文件中通过依赖加入进来-->
    <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>
    <!--自定义js-->
    <script src="/chat.js"></script>
</head>
<body>
<div id="chat">
    <div id="chatsContent">
        <div>
            请输入聊天内容:
            <input type="text" id="content" placeholder="聊天内容">
            目标用户:
            <input type="text" id="to" placeholder="目标用户">
            <button id="send" type="button">发送</button>
        </div>
    </div>
</div>
</body>
</html>

/resource/static目录下创建chat.js

var stompClient = null;

//建立一个 WebSocket 连接,在建立 WebSocket 连接时,用户必须先输入用户名,然后才能建立连接
function connect() {
    //使用 SockJS 建立连接,然后创建一个 STOMP 实例发起连接请求 在连接成功的回调方法中,
    // 首先调用 setConnected(true);方法进行页面的设置,然后调用 STOMP 中的 subscribe 方法订阅服务端发送回来的消息,并将服务端发送来的消息展示出来(使用 showGreeting 方法)
    var socket = new SockJS('/chat');
    stompClient = Stomp.over(socket);
    stompClient.connect({}, function (frame) {
        stompClient.subscribe('/user/queue/chat', function (chat) {
            showGreeting(JSON.parse(chat.body));
        });
    })
}

function sendMsg() {
    stompClient.send("/app/chat", {},
        JSON.stringify({
            'content': $("#content").val(), 'to': $("#to").val()
        }));
}

function showGreeting(message) {
    console.log("message--->",message)
    $("#chatsContent").append("<div>" + message.from + ":" + message.content + "</div>");
}

$(function () {
    connect();
    $("#send").click(function () {
        sendMsg();
    });
})

6、测试

      在浏览器地址栏中输入 http://localhost:8080/chat.html ,首先会自动跳转到 Spring Security 的默认登录页面,分别使用开始配置的两个用户 admin/123wi-gang/123 登录,登录成功后,就可以开始在线聊天了。
在这里插入图片描述
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值