如何使用jhipster运行聊天应用程序

时间:2019-04-28 15:53:17

标签: jhipster

我正在尝试使用spring websocket与jhipster 5构建聊天应用程序。 这些是我创建和配置的文件:

后端:

// WebsocketConfiguration.java

hostNetwork: true

// ChatService.java


    public static final String IP_ADDRESS = "IP_ADDRESS";

    private final JHipsterProperties jHipsterProperties;

    public WebsocketConfiguration(JHipsterProperties jHipsterProperties) {
        this.jHipsterProperties = jHipsterProperties;
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic", "/chat");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        String[] allowedOrigins = Optional.ofNullable(jHipsterProperties.getCors().getAllowedOrigins()).map(origins -> origins.toArray(new String[0])).orElse(new String[0]);
        registry.addEndpoint("/websocket/tracker", "/websocket/chat")
            .setHandshakeHandler(defaultHandshakeHandler())
            .setAllowedOrigins(allowedOrigins)
            .withSockJS()
            .setInterceptors(httpSessionHandshakeInterceptor());
    }

    @Bean
    public HandshakeInterceptor httpSessionHandshakeInterceptor() {
        return new HandshakeInterceptor() {

            @Override
            public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
                if (request instanceof ServletServerHttpRequest) {
                    ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
                    attributes.put(IP_ADDRESS, servletRequest.getRemoteAddress());
                }
                return true;
            }

            @Override
            public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {

            }
        };
    }

    private DefaultHandshakeHandler defaultHandshakeHandler() {
        return new DefaultHandshakeHandler() {
            @Override
            protected Principal determineUser(ServerHttpRequest request, WebSocketHandler wsHandler, Map<String, Object> attributes) {
                Principal principal = request.getPrincipal();
                if (principal == null) {
                    Collection<SimpleGrantedAuthority> authorities = new ArrayList<>();
                    authorities.add(new SimpleGrantedAuthority(AuthoritiesConstants.ANONYMOUS));
                    principal = new AnonymousAuthenticationToken("WebsocketConfiguration", "anonymous", authorities);
                }
                return principal;
            }
        };
    }
}

前端:

// chat.service.ts

    private static final Logger log = LoggerFactory.getLogger(ChatService.class);

    private DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    private final SimpMessageSendingOperations messagingTemplate;

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


    @SubscribeMapping("/chat/public")
    public void subscribe(StompHeaderAccessor stompHeaderAccessor, Principal principal) {
        String login =principal.getName();
        String ipAddress = stompHeaderAccessor.getSessionAttributes().get(IP_ADDRESS).toString();
        log.debug("User {} subscribed to Chat from IP {}", login, ipAddress);
        MessageDTO messageDTO = new MessageDTO();
        messageDTO.setUserLogin("System");
        messageDTO.setTime(dateTimeFormatter.format(ZonedDateTime.now()));
        messageDTO.setMessage(login + " joined the chat");
        messagingTemplate.convertAndSend("/chat/public", messageDTO);
    }

    @MessageMapping("/chat")
    @SendTo("/chat/public")
    public MessageDTO sendChat(@Payload MessageDTO messageDTO, StompHeaderAccessor stompHeaderAccessor, Principal principal) {
        messageDTO.setUserLogin(principal.getName());
        return setupMessageDTO(messageDTO, stompHeaderAccessor, principal);
    }

    @Override
    public void onApplicationEvent(SessionDisconnectEvent event) {
        // when the user disconnects, send a message saying that hey are leaving
        log.info("{} disconnected from the chat websockets", event.getUser().getName());
        MessageDTO messageDTO = new MessageDTO();
        messageDTO.setUserLogin("System");
        messageDTO.setTime(dateTimeFormatter.format(ZonedDateTime.now()));
        messageDTO.setMessage(event.getUser().getName() + " left the chat");
        messagingTemplate.convertAndSend("/chat/public", messageDTO);
    }

    private MessageDTO setupMessageDTO (MessageDTO messageDTO, StompHeaderAccessor stompHeaderAccessor, Principal principal) {
        messageDTO.setTime(dateTimeFormatter.format(ZonedDateTime.now()));
        log.debug("Sending user chat data {}", messageDTO);
        return messageDTO;
    }
}

// chat.component.ts

    constructor(
        private router: Router,
        private authServerProvider: AuthServerProvider,
        private $document: Document,
        private $window: Window,
        private csrfService: CSRFService
    ) {
        this.connection = this.createConnection();
        this.listener = this.createListener();
    }

    connect() {
        if (this.connectedPromise === null) {
          this.connection = this.createConnection();
        }
        // building absolute path so that websocket doesnt fail when 
     deploying with a context path
        const loc = this.$window.location;
        let url = '//' + loc.host + loc.pathname + 'websocket/chat';
        const authToken = this.authServerProvider.getToken();
        if (authToken) {
            url += '?access_token=' + authToken;
        }
        const socket = new SockJS(url);
        this.stompClient = Stomp.over(socket);
        const headers = {};
        this.stompClient.connect(headers, () => {
            this.connectedPromise('success');
            this.connectedPromise = null;
            this.subscribe();
            if (!this.alreadyConnectedOnce) {
                this.alreadyConnectedOnce = true;
            }
        });
    }

    disconnect() {
        if (this.stompClient !== null) {
            this.stompClient.disconnect();
            this.stompClient = null;
        }
        if (this.subscription) {
            this.subscription.unsubscribe();
            this.subscription = null;
        }
        this.alreadyConnectedOnce = false;
    }

    receive() {
        return this.listener;
    }

    sendMessage(message) {
        if (this.stompClient !== null && this.stompClient.connected) {
            this.stompClient.send(
                '/chat', // destination
                JSON.stringify({'message': message}), // body
                {} // header
            );
        }
    }

    subscribe() {
        this.connection.then(() => {
            this.subscriber = this.stompClient.subscribe('/chat/public', data 
    => {
                this.listenerObserver.next(JSON.parse(data.body));
            });
        });
    }

    unsubscribe() {
        if (this.subscriber !== null) {
            this.subscriber.unsubscribe();
        }
        this.listener = this.createListener();
    }

    private createListener(): Observable<any> {
        return new Observable(observer => {
            this.listenerObserver = observer;
        });
    }

    private createConnection(): Promise<any> {
        return new Promise((resolve, reject) => this.connectedPromise = 
    resolve);
    }

当我运行./mvnw或npm start时,出现空白页。我找不到问题。

这是我的控制台浏览器上的错误:

messages: Array<Object> = [];
    message = '';
    constructor(private chatService: ChatService) { }

   ngOnInit() {
        this.chatService.connect();

        this.chatService.receive().subscribe(message => {
            this.messages.push(message);
        });
   }

    ngOnDestroy() {
        this.chatService.unsubscribe();
    }

    sendMessage(message) {
        if (message.length === 0) {
            return;
        }
        this.chatService.sendMessage(message);
        this.message = '';
    }    

这是我的mvnw错误:

ERROR Error: Uncaught (in promise): Error: StaticInjectorError(ChatFinalAppModule)[Document]: 
  StaticInjectorError(Platform: core)[Document]: 
    NullInjectorError: No provider for Document!
Error: StaticInjectorError(ChatFinalAppModule)[Document]: 
  StaticInjectorError(Platform: core)[Document]: 
    NullInjectorError: No provider for Document!
    at NullInjector.get (core.js?09c9:8894)
    at resolveToken (core.js?09c9:9139)
    at tryResolveToken (core.js?09c9:9083)
    at StaticInjector.get (core.js?09c9:8980)
    at resolveToken (core.js?09c9:9139)
    at tryResolveToken (core.js?09c9:9083)
    at StaticInjector.get (core.js?09c9:8980)
    at resolveNgModuleDep (core.js?09c9:21119)
    at NgModuleRef_.get (core.js?09c9:21808)
    at injectInjectorOnly (core.js?09c9:1772)
    at resolvePromise (zone.js?d135:831)
    at resolvePromise (zone.js?d135:788)
    at eval (zone.js?d135:892)
    at ZoneDelegate.invokeTask (zone.js?d135:423)
    at Object.onInvokeTask (core.js?09c9:17279)
    at ZoneDelegate.invokeTask (zone.js?d135:422)
    at Zone.runTask (zone.js?d135:195)
    at drainMicroTaskQueue (zone.js?d135:601)
    at ZoneTask.invokeTask (zone.js?d135:502)
    at ZoneTask.invoke (zone.js?d135:487)

这是我使用管理员帐户登录时的mvn日志:

2019-04-28 23:28:43.153 DEBUG 12652 --- [  XNIO-2 task-2] c.p.a.aop.logging.LoggingAspect          : Enter: com.pu.askanexpert.repository.CustomAuditEventRepository.add() with argument[s] = [AuditEvent [timestamp=2019-04-28T21:28:43.136Z, principal=anonymousUser, type=AUTHORIZATION_FAILURE, data={details=org.springframework.security.web.authentication.WebAuthenticationDetails@957e: RemoteIpAddress: 127.0.0.1; SessionId: null, type=org.springframework.security.access.AccessDeniedException, message=Access is denied}]]
2019-04-28 23:28:43.163 DEBUG 12652 --- [  XNIO-2 task-2] c.p.a.aop.logging.LoggingAspect          : Exit: com.pu.askanexpert.repository.CustomAuditEventRepository.add() with result = null
2019-04-28 23:28:43.179  WARN 12652 --- [  XNIO-2 task-2] o.z.problem.spring.common.AdviceTrait    : Unauthorized: Full authentication is required to access this resource
2019-04-28 23:28:43.294  WARN 12652 --- [  XNIO-2 task-2] .m.m.a.ExceptionHandlerExceptionResolver : Resolved exception caused by handler execution: org.springframework.security.authentication.InsufficientAuthenticationException: Full authentication is required to access this resource

0 个答案:

没有答案