在SockJS+Spring Websocket中convertAndSendToUser中的“用户”来自哪里?

本文介绍了如何在Spring框架的Stomp协议中,通过自定义HandshakeHandler为每个连接生成唯一的用户名,以便向订阅特定主题的用户发送消息。同时,强调了如何在客户端和服务器端使用这些用户名进行消息传递和订阅操作。
摘要由CSDN通过智能技术生成

一、前言

我们知道可以使用客户端订阅的主题前缀从 stomp 服务器向客户端发送消息,例如 /topic/hello。我们还知道我们可以向特定用户发送消息,因为 spring 提供了convertAndSendToUser(username, destination, message)API。它接受一个字符串用户名,这意味着如果我们以某种方式为每个连接都有一个唯一的用户名,我们能够向订阅某个主题的特定用户发送消息。

那么,这个用户名来自哪里?或者说它是如何用这个用户名确定对应连接的?

二、Principal

对于上面的回答是:用户名是 java.security.Principal 的一部分。每个StompHeaderAccessor或WebSocketSession对象都有此主体的实例,我们可以从中获取用户名。但是,它不是自动生成的。它必须由服务器为每个会话手动生成。

要使用它,必须先实现它:

class StompPrincipal implements Principal {
    String name

    StompPrincipal(String name) {
        this.name = name
    }

    @Override
    String getName() {
        return name
    }
}

然后,通过覆盖 DefaultHandshakeHandler 为每个连接生成唯一的用户名。可以使用任何逻辑来生成用户名。这是使用 UUID 的一种潜在逻辑:

class CustomHandshakeHandler extends DefaultHandshakeHandler {
    @Override
    protected Principal determineUser(ServerHttpRequest request,WebSocketHandler wsHandler,Map<String, Object> attributes) {
        return new StompPrincipal(UUID.randomUUID().toString())
    }
}

最后,需要配置 Websocket 以使用自定义握手处理程序。

@Override
void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {
    stompEndpointRegistry
         .addEndpoint("/stomp") 
         .setHandshakeHandler(new CustomHandshakeHandler()) //在这里设置
         .withSockJS() 
}

三、使用

现在,服务器已配置为为每个连接生成唯一的主体名称。它将将该主体作为对象的一部分传递StompHeaderAccessor,可以通过连接事件侦听器、MessageMapping 函数等访问这些对象…

来自事件监听器:

@EventListener
void handleSessionConnectedEvent(SessionConnectedEvent event) {
    // Get Accessor
    StompHeaderAccessor sha = StompHeaderAccessor.wrap(event.getMessage())
}

来自消息映射 API:

@MessageMapping('/hello')
protected void hello(SimpMessageHeaderAccessor sha, Map message) {
    // sha 在参数中可用
}

使用convertAndSendToUser(…),向用户发送消息时,使用类似这样的内容:

convertAndSendToUser(sha.session.principal.name, '/topic/hello', message)

但是,要订阅客户端,必须使用:

client.subscribe('/user/topic/hello', callback)

如果要接收广播:

client.subscribe('/topic/hello', callback)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

timi先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值