使用react socket io和spring进行授权的websocket通信

yqkkidmi  于 2021-07-26  发布在  Java
关注(0)|答案(0)|浏览(308)

因此,我有一个使用springboot的api,并尝试实现一个websocket端点,用户在登录时可以在该端点获得订阅,并在该端点侦听不同实体创建的通知。假设我的websocket正在后台工作,下面是我的代码。

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/points_notification")
                .setAllowedOrigins("localhost:3000")
                .withSockJS();
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.enableSimpleBroker("/topic");
        registry.setApplicationDestinationPrefixes("/app");
    }
}
@Controller
public class NotificationsController {

    @Autowired private NotificationDispatcher dispatcher;

    @MessageMapping("/start")
    public void start(StompHeaderAccessor stompHeaderAccessor) {
        dispatcher.add(stompHeaderAccessor.getSessionId());
        System.out.println("GOT a session! " + stompHeaderAccessor.getSessionId());
    }

    @MessageMapping("/stop")
    public void stop(StompHeaderAccessor stompHeaderAccessor) {
        dispatcher.remove(stompHeaderAccessor.getSessionId());
    }
}
@Service
public class NotificationDispatcher {

    @Autowired
    private SimpMessagingTemplate template;
    private final Set<String> listeners = new HashSet<>();

    public <T extends Serializable> void dispatch(T addedObj) {
        for (String listener : listeners) {
            LOG.info("Sending notification to " + listener);

            SimpMessageHeaderAccessor headerAccessor = SimpMessageHeaderAccessor.create(SimpMessageType.MESSAGE);
            headerAccessor.setSessionId(listener);
            headerAccessor.setLeaveMutable(true);

            template.convertAndSendToUser(
                    listener,
                    "/topic/item",
                    new ObjWithMsgResponse<T>("Point added by: " + listener, addedObj),
                    headerAccessor.getMessageHeaders());
        }
    }
//getters and event listeners
}

当然了 dispatch() 在创建实体时被注入和调用。
在前面,我使用react并尝试处理与 socket.io-client ,我对这个有点陌生,所以我不太明白 emit 以及 on 方法是有效的,因为在文档中它们显示了您调用的和eventname,但是在spring中端点使用的是url,我在任何地方都找不到如何ping url而不是eventname。
我也试着用 SockJS 这就像一个咒语,但是端点需要身份验证,有了这个,我不能将这个头添加到socket请求中,soocket.io允许我这样做。
这是我的解决方案,它只连接但不接收或发出任何请求。

class SocketManager {
    socketRef: Socket | undefined = undefined;

    startListening(authToken: String) {
        this.socketRef = io('http://localhost:11000/weblab4/', {
            path: "/weblab4" + '/points_notification',
            transports: ['websocket'],
            extraHeaders: {
                Authorization: "Bearer " + authToken
            }
        });
        this.socketRef.emit('/app/start', {});

        this.socketRef.on('/user/topic/item', (data: INewPointNotification) => {
            console.log("received data from socket: " + data);
            toast.success('? ' + data.msg + data.point, {/*toast props*/});
        });
        console.log("socket connected", this.socketRef);
    }

    stopListening() {
        if (this.socketRef !== undefined)
            this.socketRef.disconnect();
        console.log("socket disconnected", this.socketRef);
    }
}

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题