【问题标题】:How to attach data to socket connection in order to get this data on `SessionDisconnectEvent`?如何将数据附加到套接字连接以便在 `SessionDisconnectEvent` 上获取此数据?
【发布时间】:2019-09-16 08:09:50
【问题描述】:

我想要达到的目标

当套接字在服务器端使用@EventListener 断开连接时,我想获取我用作@DestinationVariable 的字符串变量,称为lobbyName

@Component
public class WebSocketEventListener {

    private SimpMessageSendingOperations messagingTemplate;

    public WebSocketEventListener(SimpMessageSendingOperations messagingTemplate) {
        this.messagingTemplate = messagingTemplate;
    }

    @EventListener
    public void handleWebSocketDisconnectListener(SessionDisconnectEvent event) {
        //here I want to get my data
    }
}

我的问题

我一直在尝试使用SessionDisonnectEvent 获取lobbyName,但我不知道如何、何时以及在何处放置此lobbyName 以便将其放入SessionDisconnectEvent

我一直在尝试的事情

在服务器端:

@Controller
public class WebSocketController {

    private final SimpMessagingTemplate template;

    WebSocketController(SimpMessagingTemplate template) {
        this.template = template;
    }

    public void pokeLobby(@DestinationVariable String lobbyName, SocketMessage message) {
//        This didn't work 
//        Map<String, Object> headers = new HashMap<>();
//        headers.put("lobbyName", lobbyName);
//        this.template.convertAndSend("/lobby/"+lobbyName.toLowerCase(), message, headers);
        this.template.convertAndSend("/lobby/"+lobbyName.toLowerCase(), message);
    }
}

可以在客户端做吗? :

  connectToLobbyWebSocket(lobbyName: string): void {
    const ws = new SockJS(this.addressStorage.apiAddress + '/socket');
    this.stompClient = Stomp.over(ws);
    // this.stompClient.debug = null;
    const that = this;
    this.stompClient.connect({}, function () {
      that.stompClient.subscribe('/lobby/' + lobbyName, (message) => {
        if (message.body) {
          that.socketMessage.next(message.body); //client logic
        }
      });
    });
  }

编辑(进度)

由于我可以在SessionDisconnectEvent 上轻松获得sessionId,因此我决定将sessionId(握手时)更改为playerId:lobbyName:uuid 我对这个解决方案不太满意,所以如果您有任何建议,我会全力以赴。

const ws = new SockJS(this.addressStorage.apiAddress + '/socket', null, {
  sessionId: function (): string {
    return that.authManager.playerId + ':' + lobbyName + ':' + uuid();
  }
});

【问题讨论】:

    标签: java angular spring-boot websocket stomp


    【解决方案1】:

    您可以在消息正文中将 lobbyName 作为属性发送,并像这样在侦听器中获取它:

    @EventListener
    public void handleWebSocketDisconnectListener(SessionDisconnectEvent event) {
        StompHeaderAccessor headerAccessor = StompHeaderAccessor.wrap(event.getMessage());
        String lobbyName = (String) headerAccessor.getSessionAttributes().get("lobbyName");
        if(lobbyName != null) {
            SocketMessage message = new SocketMessage();
            messagingTemplate.convertAndSend("/topic/public/"+lobbyName, message);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2011-06-12
      • 1970-01-01
      • 1970-01-01
      • 2021-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-02
      相关资源
      最近更新 更多