SpringBoot中的WebSocket点对点发送消息

添加依赖:

  

<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-websocket</artifactId>
			<version>1.3.5.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-security</artifactId>
		</dependency>
配置SpringSecurity:

package com.example.demo.part3.chapter7.Chat;

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(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .inMemoryAuthentication()
                //在内存中分别配置两个用户sasa sa和密码 ,角色是user
                .withUser("sasa").password("123").roles("user")
                .and()
                .withUser("sa").password("123").roles("user");

    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        ///resources/static/ 目录下的静态资源,spring security不拦截
        web.ignoring().antMatchers("/resources/static/**");

    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                //设置spring security对 /  和  /login  路径不拦截
                .antMatchers("/","/login").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                //设置spring security的登录页面访问路径为 /login
                .loginPage("/login")
                //登陆成功后转向 /chat 路径
                .defaultSuccessUrl("/chat")
                .permitAll()
                .and()
                .logout()
                .permitAll();

    }
}


配置WebSocket:

package com.example.demo.part3.chapter7.Chat;

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 configureMessageBroker(MessageBrokerRegistry registry) {
        //点对点式应增加一个/queue消息代理
        registry.enableSimpleBroker("/queue","/topic");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry endpoint) {
        //注册一个名为 endPointChat 的endpoint
        endpoint.addEndpoint("/endPointChat").withSockJS();

    }
}
控制器:

package com.example.demo.part3.chapter7.Chat;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Controller;

import java.security.Principal;

@Controller
public class ChatController {
    @Autowired
    //通过simpleMessagingTemplate向浏览器发送消息
    private SimpMessagingTemplate messagingTemplate;
    @MessageMapping("/chat")
    //在springmvc中,可以直接在参数中获取principle,principle中包含当前用户的信息
    public  void handleChat(Principal principal,String msg){
        System.out.println(1);
        if(principal.getName().equals("sasa")){
            //通过 convertAndSendToUser方法向用户发送信息,第一个参数是消息接收人,
            //第二个是浏览器订阅地址,第三个是消息本身
            System.out.println(2);
            messagingTemplate.convertAndSendToUser("sa",
                    "/queue/notifications",principal.getName()
                    +"-send:"+msg);
        }else{
            System.out.println(3);
            messagingTemplate.convertAndSendToUser("sasa",
                    "/queue/notifications",principal.getName()
                    +"-send:"+msg);
        }
    }
}


登录页面:

<!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" name="登录"/>
       </div>
   </form>

</body>
</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>
    <script th:src="@{sockjs.min.js}"></script>
    <script th:src="@{stomp.min.js}"></script>
    <script th:src="@{jquery-1.8.3.min.js}"></script>
</head>
<body>
   <form id="chatForm">
       <textarea rows="4" cols="60" name="text" id="text" />
       <input type="submit"/>
   </form>

   <script type="text/javascript">
       $("#chatForm").submit(function (e) {
           e.preventDefault();
           var text=$("#text").val();
           sendMsg(text);
       });
       //连接endpoint名称为 /endPointChat 的endpoint
       var sock=new SockJS("/endPointChat");
       var stomp=Stomp.over(sock);
       stomp.connect('guest','guest',function (frame) {
           //订阅 /user/queue/notifications 发送的消息,这里与
           //在控制器的messagingTemplate.convertAndSendToUser中定义的订阅地址保持一致
           //这里多了 /user ,并且这个 /user是必须的,使用了 /user 才会将消息发送到指定用户
           stomp.subscribe("/user/queue/notifications",handleNotification);
       });
       function handleNotification(message) {
           console.log("msg"+message);
           $("#output").append('<b>'+message.body+'</b>');
       }

       function sendMsg(text) {
           stomp.send("/chat",{},text);
       }
       $("#stop").click(function () {
           sock.close();
       })

   </script>
 <div id="output"></div>


</body>
</html>
页面控制:

package com.example.demo.part3.chapter7.WebSocket;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter{
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        //super.addViewControllers(registry);
        registry.addViewController("/login").setViewName("/login");
        registry.addViewController("/chat").setViewName("/chat");
    }
}

效果展示:





评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值