如何使用websockets和SockJS

时间:2016-04-30 03:31:31

标签: java spring-mvc spring-security spring-websocket sockjs

我想通知所有登录用户我的应用程序中有多少用户登录/在线,这很简单我在配置方法中使用以下代码来完成WebSecurityConfigurerAdapter我只是

@Override
    protected void configure(HttpSecurity http) throws Exception {          
        http.sessionManagement().maximumSessions(1).sessionRegistry(sessionRegistry()).expiredUrl("/");

    }

在控制器方面我有

    @Autowired
    @Qualifier("sessionRegistry")
    private SessionRegistry sessionRegistry;
        @Secured("ROLE_USER")
    @RequestMapping(value = "/users/{userId}/{userName}", method = RequestMethod.GET)
    public String showUserProfile(Model model){
List<Object> principals = sessionRegistry.getAllPrincipals();

        List<String> usersNamesList = new ArrayList<String>();

        for (Object principal: principals) {
            if (principal instanceof org.springframework.security.core.userdetails.User) {
                usersNamesList.add(((org.springframework.security.core.userdetails.User) principal).getUsername());
            }
        }       

        model.addAttribute("onlineUsers", "Online users are " + usersNamesList.size());
return "layout_user_profile";

}

我得到的在线用户数量,但不是实时,我想通知所有用户一些新用户登录/注销该应用程序,我有 @EnableWebSocketMessageBroker 带注释的类

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketBrokerConfigurer extends AbstractWebSocketMessageBrokerConfigurer{

    @Override
    public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {
        stompEndpointRegistry.addEndpoint("/users")
        .setHandshakeHandler(new CurrentLoggeInUserHandshakeHandler())
        .withSockJS();      
    }

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

    }

    class CurrentLoggeInUserHandshakeHandler extends DefaultHandshakeHandler{


        @Override
        protected Principal determineUser(ServerHttpRequest request,
                WebSocketHandler wsHandler, Map<String, Object> attributes) {
            User user = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            String username = user.getUsername();
            return new UsernamePasswordAuthenticationToken(username, null);
        }   

    }

}

我的客户端是

<script type="text/javascript">
    var webSocketC;
    var stompClient;
    $(document).ready(function(){

        webSocketC = new SockJS('/app/users');

        stompClient = Stomp.over(webSocketC);

        stompClient.connect({}, function(frame){
            stompClient.subscribe('/topic/users', function(message){
                //TODO Here
            });

        }, function(error){         
                console.log("error " +  error);         
        });     
    });
    </script>

使用此代码我将浏览器控制台输出视为

Opening Web Socket...
stomp.js:134 Web Socket Opened...
stomp.js:134 >>> CONNECT
accept-version:1.1,1.0
heart-beat:10000,10000

<<< CONNECTED
version:1.1
heart-beat:0,0
user-name:john-doe@mail.com

connected to server undefined
stomp.js:134 >>> SUBSCRIBE
id:sub-0
destination:/topic/users

结论

我找不到向所有用户发送消息的方法,无论我使用 @EnableWebSocketMessageBroker 带注释的类发送该通知,还是客户端代码是完成所需技巧的地方?以及如何做到这一点?

1 个答案:

答案 0 :(得分:0)

Color

这样的事情应该做。