Клиент WebSocket на основе JavaScript не получает никаких выходных данных в консоль браузера с использованием веб-сокетов Spring Reactor - PullRequest
0 голосов
/ 07 мая 2020

Я следовал руководству по настройке веб-сокетов, в которых использовался Pivotal Reactor Framework API.

В этом примере после запуска Spring Boot Reactive Microservice запускается веб-браузер Google Chrome и открытие определенного c URL (с портом), затем щелчок по View / Source, а затем по Console.

Это должно было привести к появлению сообщения журнала для стандартного вывода консоли Google Chrome.

Однако ничего не выводится ...


Структура проекта:

rswebsockets
│
├── build.gradle
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── src
    ├── main
    │   ├── java
    │   │   └── com
    │   │       └── reactive
    │   │           ├── RsWebSocketsApplication.java
    │   │           ├── config
    │   │           │   └── WebSocketConfig.java
    │   │           ├── model
    │   │           │   ├── GreetingRequest.java
    │   │           │   └── GreetingResponse.java
    │   │           └── service
    │   │               └── GreetingService.java
    │   └── resources
    │       ├── application.properties
    │       └── static
    │           └── ws.html
    └── test
        └── java
            └── com
                └── reactive
                    └── RsWebSocketsApplicationTests.java

build.gradle:

plugins {
    id 'org.springframework.boot' version '2.2.6.RELEASE'
    id 'io.spring.dependency-management' version '1.0.9.RELEASE'
    id 'java'
}

group = 'com.reactive'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '14'

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-webflux'
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation('org.springframework.boot:spring-boot-starter-test') {
        exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    }
    testImplementation 'io.projectreactor:reactor-test'
}

test {
    useJUnitPlatform()
}

Кодовая база:

rswebsockets / src / main / java / com / reactive / RsWebSocketsApplication. java:

package com.reactive;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class RsWebSocketsApplication {

    public static void main(String[] args) {
        SpringApplication.run(RsWebSocketsApplication.class, args);
    }

}

rswebsockets / src / main / java / com / reactive / config / WebSocketConfig. java:

package com.reactive.config;

import com.reactive.model.GreetingRequest;
import com.reactive.model.GreetingResponse;
import com.reactive.service.GreetingService;
import org.springframework.context.annotation.Bean;
import org.springframework.web.reactive.handler.SimpleUrlHandlerMapping;
import org.springframework.web.reactive.socket.WebSocketHandler;
import org.springframework.web.reactive.socket.WebSocketMessage;
import org.springframework.web.reactive.socket.server.support.WebSocketHandlerAdapter;

import java.util.Map;

public class WebSocketConfig {

    @Bean
    SimpleUrlHandlerMapping simpleUrlHandlerMapping(WebSocketHandler wsh) {
        return new SimpleUrlHandlerMapping(Map.of("/ws/greetings", wsh), 10);
    }

    @Bean
    WebSocketHandler webSocketHandler(GreetingService greetingService) {
        return session -> {
           var receive = session
                            .receive()
                            .map(WebSocketMessage::getPayloadAsText)
                            .map(GreetingRequest::new)
                            .flatMap(greetingService::greet)
                            .map(GreetingResponse::getMessage)
                            .map(session::textMessage);
           return session.send(receive);
        };
    }

    @Bean
    WebSocketHandlerAdapter webSockerHandlerAdapter() {
        return new WebSocketHandlerAdapter();
    }
}

rswebsockets / src / main / java / com / reactive / model / GreetingRequest. java:

package com.reactive.model;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class GreetingRequest {

    String name;

}

rswebsockets / src / main / java / com / reactive / model / GreetingResponse. java:

package com.reactive.model;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class GreetingResponse {

    String message;

}

rswebsockets / src / main / java / com / reactive / service / GreetingService. java:

package com.reactive.service;

import com.reactive.model.GreetingRequest;
import com.reactive.model.GreetingResponse;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;

import java.time.Duration;
import java.time.Instant;
import java.util.stream.Stream;

@Service
public class GreetingService {

    public Flux<GreetingResponse> greet(GreetingRequest request) {
        return Flux.fromStream(
                Stream.generate(() -> new GreetingResponse("Hello " + request.getName() + " @ " + Instant.now())))
                      .delayElements(Duration.ofSeconds(1));

    }
}

rswebsockets / src / main / resources / static / ws. html:

<html>
<body>
<script>
    window.addEventListener('load', function (e) {
        var ws = new WebSocket('ws://localhost:8080/ws/greetings')
        ws.addEventListener('open', function (e) {
            ws.send('Livelessons Fans')
        });
        ws.addEventListener('message', function (e) {
            console.log(e.data);
        });

    })
</script>
</body>
</html>

После запуска микросервис (ничего не ломается при запуске), используя:

gradle bootRun

вывод:

Java HotSpot(TM) 64-Bit Server VM warning: Options -Xverify:none and -noverify were deprecated in JDK 13 and will likely be removed in a future release.

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.2.6.RELEASE)

2020-05-06 14:46:41.393  INFO 39122 --- [           main] com.reactive.RsWebSocketsApplication     : Starting RsWebSocketsApplication on Porsche959.local with PID 39122 (/Users/pnwlover/rswebsockets/build/classes/java/main started by pnwlover in /Users/pnwlover/rswebsockets)
2020-05-06 14:46:41.395  INFO 39122 --- [           main] com.reactive.RsWebSocketsApplication     : No active profile set, falling back to default profiles: default
2020-05-06 14:46:42.126  INFO 39122 --- [           main] o.s.b.web.embedded.netty.NettyWebServer  : Netty started on port(s): 8080
2020-05-06 14:46:42.129  INFO 39122 --- [           main] com.reactive.RsWebSocketsApplication     : Started RsWebSocketsApplication in 0.941 seconds (JVM running for 1.579)

Открыл Google Chrome и запустил следующий URL:

http://localhost:8080/ws.html

Открыл Google Chrome Инструменты разработчика, перейдя на страницу просмотра rce, а затем щелкнув вкладку Консоль:

Google Chrome Console Tab


Инструменты разработчика Google Chome - вкладка «Источники»:

Google Chome Developer Tools Sources Tab


Что я делаю не так?

1 Ответ

0 голосов
/ 07 мая 2020

Все заработало, поместив @Configuration над классом WebSocketConfig:

@Configuration
public class WebSocketConfig { 

    // Methods omitted for brevity.
}

enter image description here

...