【发布时间】:2019-05-04 17:09:34
【问题描述】:
我们正在使用 Spring Boot WebSocket 开发一个聊天应用程序。 用户可以登录到托管在 Tomcat 中的聊天应用程序,并向其他在线用户发送消息。 我们无法从另一个 iOS 客户端连接到同一个聊天应用程序。
下面是我们在服务端和客户端的代码实现
///////////////////////////////////////////
// Server side implementation
///////////////////////////////////////////
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/message");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/tracking").withSockJS();
}
}
@Configuration
@EnableWebSocketMessageBroker
public class WebsocketConfiguration implements WebSocketMessageBrokerConfigurer {
private final Logger log = LoggerFactory
.getLogger(WebsocketConfiguration.class);
public static final String IP_ADDRESS = "IP_ADDRESS";
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/message");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
log.debug("registering StompEndpoints");
registry.addEndpoint("/websocket/tracker")
.setHandshakeHandler(new DefaultHandshakeHandler() {
// custom authentication
}).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) {
}
};
}
}
///////////////////////////////////////////
// Web Client side socket creation code
///////////////////////////////////////////
var stompClient = null;
function connect() {
if (stompClient != null) {
stompClient.disconnect();
}
var socket = new SockJS(contextPath + '/tracking');
stompClient = Stomp.over(socket);
stompClient.connect({}, function(frame) {
stompClient.subscribe('/message/send/individual/' + loginUserUk,
function(response) {
var messageBody1 = JSON.parse(response.body);
//process with the response
});
});
}
///////////////////////////////////////////
// IOS Client side code
///////////////////////////////////////////
let host = "xxx.xxx.x.xx:8080/tracking"
let socket = WebSocket(url: URL(string: "wss://\(host)/")!, protocols:[])
socket.delegate = self
socket.connect()
func websocketDidConnect(socket: WebSocketClient) {
print("websocket is connected")
}
func websocketDidDisconnect(socket: WebSocketClient, error: Error?) {
if let e = error as? WSError {
print("websocket is disconnected: \(e.message)")
} else if let e = error {
print("websocket is disconnected: \(e.localizedDescription)")
} else {
print("websocket disconnected")
}
}
func websocketDidReceiveMessage(socket: WebSocketClient, text: String) {
print("Received text: \(text)")
}
func websocketDidReceiveData(socket: WebSocketClient, data: Data) {
print("Received data: \(data.count)")
}
当我们尝试从 iOS 连接时(在上面的代码 sn-p 中提供),我们收到以下错误:TCP Conn 0x109de3d50 SSLHandshake failed (-9847) websocket is disconnected: The operation could not be completed.
非常感谢任何帮助。提前致谢。
【问题讨论】:
-
您已将其标记为“swift”,但您发布的代码(客户端)是 JavaScript。此外,您没有提供有关尝试连接到服务器时收到的任何错误消息的信息。如果我们要帮助您,我们需要的不仅仅是“无法连接”。
-
当我们尝试从 iOS 连接时(在上面的代码 sn-p 中提供),我们收到以下错误:TCP Conn 0x109de3d50 SSLHandshake failed (-9847) websocket is disconnected: The operation could'未完成。
-
您确定服务器具有有效的 SSL 证书吗?如果您有应用程序的源代码,请尝试将“应用程序传输安全性 > 允许任意加载”暂时设置为“是”,看看是否能解决问题。如果是这样,那么您的服务器具有无效或自签名证书。
-
谢谢。我们已经从letsencrypt设置了免费的SSL证书。我们还尝试在 IOS 应用程序代码中将“允许任意负载”永久设置为“是”。
-
您看到的错误肯定是 SSL,因此请检查您的服务器是否配置正确。 Allow Arbitrary Loads 将允许任何 SSL 证书,所以如果这不起作用,那么几乎可以肯定是服务器问题。检查服务器是否确实正确应用了证书(可能需要重新启动)。您网络上的错误防火墙/路由器配置也可能导致 SSL 问题。