Attempt to socket connect before establishing websocket connection
Summary: ^ Changelog: Check if there's a process listening at the specified port before attempting to establish a websocket connection on iOS Reviewed By: fabiomassimo Differential Revision: D35546817 fbshipit-source-id: 92ccca9afd8bcdc6d79205cc277ac813e0999166
This commit is contained in:
committed by
Facebook GitHub Bot
parent
f7fc00cde2
commit
fd2d7bc1a4
@@ -10,6 +10,10 @@
|
|||||||
#import "FlipperPlatformWebSocket.h"
|
#import "FlipperPlatformWebSocket.h"
|
||||||
#import <Flipper/Log.h>
|
#import <Flipper/Log.h>
|
||||||
#import <SocketRocket/SocketRocket.h>
|
#import <SocketRocket/SocketRocket.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
static constexpr int connectionKeepaliveSeconds = 10;
|
static constexpr int connectionKeepaliveSeconds = 10;
|
||||||
|
|
||||||
@@ -140,6 +144,57 @@ static constexpr int connectionKeepaliveSeconds = 10;
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Before attempting to establish a connection, check if
|
||||||
|
// there is a process listening at the specified port.
|
||||||
|
// CFNetwork seems to be quite verbose when the host cannot be reached
|
||||||
|
// causing unnecessary and annoying logs to be printed to the console.
|
||||||
|
struct addrinfo hints;
|
||||||
|
|
||||||
|
memset(&hints, 0, sizeof(hints));
|
||||||
|
hints.ai_family = AF_UNSPEC;
|
||||||
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
hints.ai_flags = AI_PASSIVE;
|
||||||
|
struct addrinfo* address;
|
||||||
|
getaddrinfo(
|
||||||
|
_url.host.UTF8String, _url.port.stringValue.UTF8String, &hints, &address);
|
||||||
|
|
||||||
|
int sfd =
|
||||||
|
socket(address->ai_family, address->ai_socktype, address->ai_protocol);
|
||||||
|
|
||||||
|
fcntl(sfd, F_SETFL, O_NONBLOCK);
|
||||||
|
connect(sfd, address->ai_addr, address->ai_addrlen);
|
||||||
|
|
||||||
|
fd_set fdset;
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
|
FD_ZERO(&fdset);
|
||||||
|
FD_SET(sfd, &fdset);
|
||||||
|
// Set a timeout of 3 seconds.
|
||||||
|
tv.tv_sec = 3;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
|
||||||
|
bool listening = false;
|
||||||
|
if (select(sfd + 1, NULL, &fdset, NULL, &tv) == 1) {
|
||||||
|
int so_error;
|
||||||
|
socklen_t len = sizeof so_error;
|
||||||
|
|
||||||
|
getsockopt(sfd, SOL_SOCKET, SO_ERROR, &so_error, &len);
|
||||||
|
|
||||||
|
if (so_error == 0) {
|
||||||
|
listening = true;
|
||||||
|
}
|
||||||
|
// If there's an error, most likely there is no process
|
||||||
|
// listening at the specified host/port (ECONNREFUSED).
|
||||||
|
}
|
||||||
|
|
||||||
|
freeaddrinfo(address);
|
||||||
|
close(sfd);
|
||||||
|
|
||||||
|
if (!listening) {
|
||||||
|
_eventHandler(facebook::flipper::SocketEvent::ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
self.socket = [[SRWebSocket alloc] initWithURL:_url securityPolicy:_policy];
|
self.socket = [[SRWebSocket alloc] initWithURL:_url securityPolicy:_policy];
|
||||||
[_socket setDelegate:self];
|
[_socket setDelegate:self];
|
||||||
[_socket open];
|
[_socket open];
|
||||||
|
|||||||
Reference in New Issue
Block a user