在spring boot中使用webSocket组件(二)

该篇演示如何使用websocket创建一对一的聊天室,废话不多说,我们马上开始!

一.首先先创建前端页面,代码如下图所示:

1.login.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
      xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<meta charset="UTF-8" />
<head>
    <title>登陆页面</title>
</head>
<body>
<div th:if="${param.error}">
    无效的账号和密码
</div>
<div th:if="${param.logout}">
    你已注销
</div>
<form th:action="@{/login}" method="post">
    <div><label> 账号 : <input type="text" name="username"/> </label></div>
    <div><label> 密码: <input type="password" name="password"/> </label></div>
    <div><input type="submit" value="登陆"/></div>
</form>
</body>
</html>

2.chat.html

<!DOCTYPE html>

<html xmlns:th="http://www.thymeleaf.org">
<meta charset="UTF-8" />
<head>
    <title>Home</title>
    <script th:src="@{sockjs.min.js}"></script>
    <script th:src="@{stomp.min.js}"></script>
    <script th:src="@{jquery.js}"></script>
</head>
<body>
<p>
    聊天室
</p>

<form id="wiselyForm">
    <textarea rows="4" cols="60" name="text"></textarea>
    <input type="submit"/>
</form>

<script th:inline="javascript">
    $('#wiselyForm').submit(function(e){
        e.preventDefault();
        var text = $('#wiselyForm').find('textarea[name="text"]').val();
        sendSpittle(text);
    });

    var sock = new SockJS("/endpointChat"); //1
    var stomp = Stomp.over(sock);
    stomp.connect('guest', 'guest', function(frame) {
        stomp.subscribe("/user/queue/notifications", handleNotification);//2
    });

    function handleNotification(message) {
        $('#output').append("<b>Received: " + message.body + "</b><br/>")
    }

    function sendSpittle(text) {
        stomp.send("/chat", {}, text);//3
    }
    $('#stop').click(function() {sock.close()});
</script>

<div id="output"></div>
</body>
</html>

二.在spring boot中创建spring Security,代码如下图所示:

(spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。通俗地讲就是为你的系统提供安全权限,不是什么人都能访问你的系统,只有有权限的人才行!)

1.先在pom.xml中引入spring Security的依赖,代码如下图所示:

            <!--spring-boot-security安全框架-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>

 

2.WebSecurityConfig类

package com.wisely.ch7_6;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/","/login").permitAll()//1根路径和/login路径不拦截
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/login") //2登陆页面
                .defaultSuccessUrl("/chat") //3登陆成功转向该页面
                .permitAll()
                .and()
                .logout()
                .permitAll();
    }
    //4
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth
                .inMemoryAuthentication()
                .withUser("dzz").password("dzz").roles("USER")//这里两个是分别账号和密码(账号:dzz密码:dzz)
                .and()
                .withUser("zbb").password("zbb").roles("USER");//这里两个是分别账号和密码(账号:zbb密码:zbb)
    }
    //5忽略静态资源的拦截
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/resources/static/**");
    }
}

3.在原来的WsController类中增加聊天的方法handleChat(),代码如下图所示:

    @Autowired
    private SimpMessagingTemplate messagingTemplate;//1

    @MessageMapping("/chat")
    public void handleChat(Principal principal, String msg) { //2
        if (principal.getName().equals("dzz")) {//3
            messagingTemplate.convertAndSendToUser("zbb",
                    "/queue/notifications", principal.getName() + "-send:"
                            + msg);
        } else {
            messagingTemplate.convertAndSendToUser(dzz",
                    "/queue/notifications", principal.getName() + "-send:"
                            + msg);
        }
    }
}

(1)SimpMessagingTemplate用于向浏览器发送信息。

(2)在spring mvc中,principal包含了登录用户的信息,在这里我们直接用。

(3)这里是一段写死的代码,如果登录的用户是dzz,那就将消息发送给zbb,大家根据自己的需求进行修改。通过convertAndSendToUser()方法进行发送,第一个参数是信息接收的目标,第二个参数是要发送的地址,第三个参数是要发送的信息。

4.在原来的WebSocketConfig类中再创建一个节点(endpoint)和代理(MessageBroker),代码如下图所示:

package com.wisely.ch7_6;

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

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer{

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/endpointWisely").withSockJS();
        registry.addEndpoint("/endpointChat").withSockJS();//1
    }


    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.enableSimpleBroker("/queue","/topic"); //2
    }

}

5.在原来的WebMvcConfig类中加入/login和/chat的映射,如下图:

           registry.addViewController("/login").setViewName("/login");
           registry.addViewController("/chat").setViewName("/chat");

三.效果演示

用两个账号登录后,如图所示:

 

 

dzz发送消息后zbb就能收到消息了,如图所示:

 

websocket的一对一聊天演示到此就结束了,如有错误,欢迎指正。

posted @ 2016-12-16 10:46  好记性不如写博客  阅读(7847)  评论(9编辑  收藏  举报