【问题标题】:Why client cannot connect to the Java Websocket server?为什么客户端无法连接到 Java Websocket 服务器?
【发布时间】:2018-04-09 13:44:54
【问题描述】:

我正在使用 Spring 5 学习 websockets。我使用 this tutorial。但是当我尝试通过 JavaScript 连接到 websocket 时,出现以下错误:

WebSocket connection to 'ws://localhost:8080/event-emitter' failed: Error during WebSocket handshake: Unexpected response code: 404

当我尝试通过 Java 连接到 websocket 时,出现以下错误:

Exception in thread "main" reactor.ipc.netty.http.client.HttpClientException: HTTP request failed with code: 404.
Failing URI: /event-emitter
Suppressed: java.lang.Exception: #block terminated with an error
    at reactor.core.publisher.BlockingSingleSubscriber.blockingGet(BlockingSingleSubscriber.java:126)
    at reactor.core.publisher.Mono.block(Mono.java:1185)

我的ReactAndSpringDataRestApplication.java

@SpringBootApplication
public class ReactAndSpringDataRestApplication {

@Autowired
private ReactiveWebSocketHandler webSocketHandler;

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

@Bean
public HandlerMapping webSocketHandlerMapping() {
    Map<String, WebSocketHandler> map = new HashMap<>();
    map.put("/event-emitter", webSocketHandler);

    SimpleUrlHandlerMapping handlerMapping = new SimpleUrlHandlerMapping();
    handlerMapping.setOrder(1);
    handlerMapping.setUrlMap(map);
    return handlerMapping;
}
@Bean
public WebSocketHandlerAdapter handlerAdapter() {
    return new WebSocketHandlerAdapter();
}
}

ReactiveWebSocketHandler.java

@Component
public class ReactiveWebSocketHandler implements WebSocketHandler {

private static final ObjectMapper json = new ObjectMapper();

private Flux<String> eventFlux = Flux.generate(sink -> {
    EventTwo event = new EventTwo(Double.toString(Math.random()), new Date().toString());
    try {
        sink.next(json.writeValueAsString(event));
    } catch (JsonProcessingException e) {
        sink.error(e);
    }
});
private Flux<String> intervalFlux = Flux.interval(Duration.ofMillis(1000L))
        .zipWith(eventFlux, (time, event) -> event);

@Override
public Mono<Void> handle(WebSocketSession webSocketSession) {
    return webSocketSession.send(intervalFlux
            .map(webSocketSession::textMessage))
            .and(webSocketSession.receive()
                    .map(WebSocketMessage::getPayloadAsText)
                    .log());
}
}

尝试连接到 websocket 的 JavaScript:

import React, {Component} from 'react';
import { connect } from 'react-redux';
import '../res/messages.css';
class Messages extends Component {

constructor(props) {
    super(props);
    this.state = {messages: []};
}

getInitialState(){
    return { messages : [] }
}

componentDidMount() {
    var clientWebSocket = new WebSocket("ws://localhost:8080/event-emitter");
    clientWebSocket.onopen = function() {
        console.log("clientWebSocket.onopen", clientWebSocket);
        console.log("clientWebSocket.readyState", "websocketstatus");
        clientWebSocket.send("event-me-from-browser");
    }
    clientWebSocket.onclose = function(error) {
        console.log("clientWebSocket.onclose", clientWebSocket, error);
    }
    clientWebSocket.onerror = function(error) {
        console.log("clientWebSocket.onerror", clientWebSocket, error);
    }
    clientWebSocket.onmessage = function(error) {
        console.log("clientWebSocket.onmessage", clientWebSocket, error);
        this.setState({
                        messages : this.state.messages.concat([ new Date() ])
                    })
    }
}

render() {
    return (
        <div><ul>{ this.state.messages.map( (msg, idx) => <li key={'msg-' + idx }>{ msg }</li> )}</ul></div>
    )
}
}

Java端\Spring中是否应该有额外的websockets配置?为什么客户端连接不上服务器?

【问题讨论】:

    标签: java spring spring-boot websocket


    【解决方案1】:

    我使用了另一个guide的配置。

    我在没有 userStats() 的情况下创建了 ChatSocketHandler.javaReactiveChatApplication.java

    我的Event.java

    @Data
    public class Event {
    private String eventId;
    private String eventDt;
    
    public Event() {
    }
    
    public Event(String eventId, String eventDt) {
        this.eventId = eventId;
        this.eventDt = eventDt;
    }
    
    public String getEventId() {
        return eventId;
    }
    
    public void setEventId(String eventId) {
        this.eventId = eventId;
    }
    
    public String getEventDt() {
        return eventDt;
    }
    
    public void setEventDt(String eventDt) {
        this.eventDt = eventDt;
    }
    }
    

    还有我的 JavaScript 文件:

    import React, {Component} from 'react';
    import { connect } from 'react-redux';
    import '../res/messages.css';
    const client = require('../client');
    
    class Messages extends Component {
    
    constructor(props) {
        super(props);
        this.state = {messages: []};{messages: []};
    }
    
    getInitialState(){
        return { messages : [] }
    }
    
    updateMessages(msg){
        this.setState({
            messages : this.state.messages.concat([ msg ])
        })
    }
    
    componentDidMount() {
        var clientWebSocket = new WebSocket("ws://127.0.0.1:8080/websocket/chat");
        clientWebSocket.onopen = function() {
            console.log("clientWebSocket.onopen", clientWebSocket);
            console.log("clientWebSocket.readyState", "websocketstatus");
            clientWebSocket.send("event-me-from-browser");
        }
        clientWebSocket.onclose = function(error) {
            console.log("clientWebSocket.onclose", clientWebSocket, error);
        }
        clientWebSocket.onerror = function(error) {
            console.log("clientWebSocket.onerror", clientWebSocket, error);
        }
        var tmpMsg;
        var _this = this;
        clientWebSocket.onmessage = function(dataFromServer) {
            console.log("clientWebSocket.onmessage", clientWebSocket, dataFromServer);
            var date =  new Date() ;
            tmpMsg =  dataFromServer;
            _this.updateMessages(tmpMsg);
        }
    
    }
    
    render() {
        return (
            <div>
                <ul>{ this.state.messages.map( (msg) =>
                    <li>{ JSON.parse(msg.data).eventDt }</li> )}
                </ul>
            </div>
    
        )
    }
    

    【讨论】:

      【解决方案2】:

      您是否在上下文(@Bean)上添加了 WebSocketHandlerAdapter 类?如果没有,请尝试在上下文中添加 WebSocketHandlerAdapter 类。

      private final WebSocketHandler webSocketHandler;
      
      @Bean
      public HandlerMapping webSocketHandlerMapping() {
          Map<String, WebSocketHandler> map = new HashMap<>();
          map.put("/event-emitter", webSocketHandler);
      
          SimpleUrlHandlerMapping handlerMapping = new SimpleUrlHandlerMapping();
          handlerMapping.setOrder(1);
          handlerMapping.setUrlMap(map);
          return handlerMapping;
      }
      
      @Bean
      public WebSocketHandlerAdapter handlerAdapter() {
          return new WebSocketHandlerAdapter();
      }
      

      【讨论】:

        猜你喜欢
        • 2013-12-09
        • 1970-01-01
        • 1970-01-01
        • 2020-01-20
        • 2020-12-11
        • 2014-11-19
        • 2022-01-21
        • 2016-07-07
        • 1970-01-01
        相关资源
        最近更新 更多