我们正在使用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连接(上述代码段中提供)时,出现以下错误:TCP Conn 0x109de3d50 SSLHandshake失败(-9847)websocket已断开连接:该操作无法完成。
非常感谢您的帮助。预先感谢。
答案 0 :(得分:0)
我认为问题出在您从iOS客户端使用的URL。 Websocket在HTTP之上运行,一旦HTTP连接建立,客户端和服务器就通过TCP进行通信。
从浏览器连接客户端时,您要做的只是启动HTTP请求。服务器确认请求后,将与客户端浏览器建立TCP连接。在这里使用SockJS(contextPath +'/ tracking');通过TCP层发送消息。
要将iOS客户端与同一台服务器连接,您要做的就是发送HTTP请求,而不是发送带有“ wss:”的请求。只要您从iOS客户端发送带有正确终结点的请求,就可以了。
let host = "xxx.xxx.x.xx:8080/tracking"
let socket = WebSocket(url: URL(string: "http://\(host)/")!, protocols:[])
socket.delegate = self
socket.connect()