more cleanup to propagate server connection error and let onOpen callback execute

This commit is contained in:
Benjamin Sergeant 2018-12-31 12:43:47 -08:00
parent 3febc2431d
commit f8373dc666
6 changed files with 53 additions and 39 deletions

View File

@ -31,9 +31,18 @@ int main(int argc, char** argv)
const ix::WebSocketCloseInfo& closeInfo, const ix::WebSocketCloseInfo& closeInfo,
const ix::WebSocketHttpHeaders& headers) const ix::WebSocketHttpHeaders& headers)
{ {
if (messageType == ix::WebSocket_MessageType_Message) if (messageType == ix::WebSocket_MessageType_Open)
{ {
std::cout << str << std::endl; std::cout << "New connection" << std::endl;
std::cout << "Headers:" << std::endl;
for (auto it : headers)
{
std::cerr << it.first << ": " << it.second << std::endl;
}
}
else if (messageType == ix::WebSocket_MessageType_Message)
{
std::cerr << str << std::endl;
webSocket.send(str); webSocket.send(str);
} }
} }

View File

@ -105,10 +105,10 @@ namespace ix
{ {
{ {
std::lock_guard<std::mutex> lock(_configMutex); std::lock_guard<std::mutex> lock(_configMutex);
_ws.configure(_url, _perMessageDeflateOptions); _ws.configure(_perMessageDeflateOptions);
} }
WebSocketInitResult status = _ws.init(); WebSocketInitResult status = _ws.connectToUrl(_url);
if (!status.success) if (!status.success)
{ {
return status; return status;
@ -120,9 +120,23 @@ namespace ix
return status; return status;
} }
void WebSocket::setSocketFileDescriptor(int fd) WebSocketInitResult WebSocket::connectToSocket(int fd)
{ {
_ws.initFromSocket(fd); {
std::lock_guard<std::mutex> lock(_configMutex);
_ws.configure(_perMessageDeflateOptions);
}
WebSocketInitResult status = _ws.connectToSocket(fd);
if (!status.success)
{
return status;
}
_onMessageCallback(WebSocket_MessageType_Open, "", 0,
WebSocketErrorInfo(), WebSocketCloseInfo(),
status.headers);
return status;
} }
bool WebSocket::isConnected() const bool WebSocket::isConnected() const

View File

@ -100,6 +100,7 @@ namespace ix
// Server // Server
void setSocketFileDescriptor(int fd); void setSocketFileDescriptor(int fd);
WebSocketInitResult connectToSocket(int fd);
WebSocketTransport _ws; WebSocketTransport _ws;

View File

@ -71,9 +71,8 @@ namespace ix
// to allow that, but this is a bit of a pain. (this is what node or python would do). // to allow that, but this is a bit of a pain. (this is what node or python would do).
// //
// Using INADDR_LOOPBACK also does not work ... while it should. // Using INADDR_LOOPBACK also does not work ... while it should.
// Using localhost or 127.0.0.1 seems to work.
// //
server.sin_addr.s_addr = inet_addr("localhost"); server.sin_addr.s_addr = inet_addr("127.0.0.1");
if (bind(_serverFd, (struct sockaddr *)&server, sizeof(server)) < 0) if (bind(_serverFd, (struct sockaddr *)&server, sizeof(server)) < 0)
{ {
@ -103,17 +102,15 @@ namespace ix
{ {
for (;;) for (;;)
{ {
/* // Accept a connection.
* Accept a connection. struct sockaddr_in client; // client address information
*/ int clientFd; // socket connected to client
struct sockaddr_in client; /* client address information */
int clientFd; /* socket connected to client */
socklen_t addressLen = sizeof(socklen_t); socklen_t addressLen = sizeof(socklen_t);
if ((clientFd = accept(_serverFd, (struct sockaddr *)&client, &addressLen)) == -1) if ((clientFd = accept(_serverFd, (struct sockaddr *)&client, &addressLen)) == -1)
{ {
std::cerr << "WebSocketServer::run() error accepting connection: " std::cerr << "WebSocketServer::run() error accepting connection: "
<< strerror(errno); << strerror(errno);
continue; continue;
} }
@ -127,11 +124,11 @@ namespace ix
void WebSocketServer::handleConnection(int fd) void WebSocketServer::handleConnection(int fd)
{ {
ix::WebSocket webSocket; ix::WebSocket webSocket;
webSocket.setSocketFileDescriptor(fd);
webSocket.start();
_onConnectionCallback(webSocket); _onConnectionCallback(webSocket);
webSocket.start();
webSocket.connectToSocket(fd); // FIXME: we ignore the return value
// We can probably do better than this busy loop, with a condition variable. // We can probably do better than this busy loop, with a condition variable.
for (;;) for (;;)
{ {

View File

@ -54,10 +54,8 @@ namespace ix
; ;
} }
void WebSocketTransport::configure(const std::string& url, void WebSocketTransport::configure(const WebSocketPerMessageDeflateOptions& perMessageDeflateOptions)
const WebSocketPerMessageDeflateOptions& perMessageDeflateOptions)
{ {
_url = url;
_perMessageDeflateOptions = perMessageDeflateOptions; _perMessageDeflateOptions = perMessageDeflateOptions;
_enablePerMessageDeflate = _perMessageDeflateOptions.enabled(); _enablePerMessageDeflate = _perMessageDeflateOptions.enabled();
} }
@ -223,18 +221,18 @@ namespace ix
} }
// Client // Client
WebSocketInitResult WebSocketTransport::init() WebSocketInitResult WebSocketTransport::connectToUrl(const std::string& url)
{ {
std::string protocol, host, path, query; std::string protocol, host, path, query;
int port; int port;
_requestInitCancellation = false; _requestInitCancellation = false;
if (!WebSocketTransport::parseUrl(_url, protocol, host, if (!WebSocketTransport::parseUrl(url, protocol, host,
path, query, port)) path, query, port))
{ {
return WebSocketInitResult(false, 0, return WebSocketInitResult(false, 0,
std::string("Could not parse URL ") + _url); std::string("Could not parse URL ") + url);
} }
if (protocol == "wss") if (protocol == "wss")
@ -299,7 +297,7 @@ namespace ix
if (!writeBytes(ss.str())) if (!writeBytes(ss.str()))
{ {
return WebSocketInitResult(false, 0, std::string("Failed sending GET request to ") + _url); return WebSocketInitResult(false, 0, std::string("Failed sending GET request to ") + url);
} }
// Read first line // Read first line
@ -309,7 +307,7 @@ namespace ix
{ {
if (!readByte(line+i)) if (!readByte(line+i))
{ {
return WebSocketInitResult(false, 0, std::string("Failed reading HTTP status line from ") + _url); return WebSocketInitResult(false, 0, std::string("Failed reading HTTP status line from ") + url);
} }
} }
line[i] = 0; line[i] = 0;
@ -383,7 +381,7 @@ namespace ix
} }
// Server // Server
WebSocketInitResult WebSocketTransport::initFromSocket(int fd) WebSocketInitResult WebSocketTransport::connectToSocket(int fd)
{ {
_requestInitCancellation = false; _requestInitCancellation = false;
@ -393,6 +391,8 @@ namespace ix
_socket.reset(); _socket.reset();
_socket = std::make_shared<Socket>(fd); _socket = std::make_shared<Socket>(fd);
std::string remote = std::string("remote fd ") + std::to_string(fd);
// Read first line // Read first line
char line[256]; char line[256];
int i; int i;
@ -400,13 +400,13 @@ namespace ix
{ {
if (!readByte(line+i)) if (!readByte(line+i))
{ {
return WebSocketInitResult(false, 0, std::string("Failed reading HTTP status line from ") + _url); return WebSocketInitResult(false, 0, std::string("Failed reading HTTP status line from ") + remote);
} }
} }
line[i] = 0; line[i] = 0;
if (i == 255) if (i == 255)
{ {
return WebSocketInitResult(false, 0, std::string("Got bad status line connecting to ") + _url); return WebSocketInitResult(false, 0, std::string("Got bad status line connecting to ") + remote);
} }
std::cout << "initFromSocket::start" << std::endl; std::cout << "initFromSocket::start" << std::endl;
@ -438,13 +438,9 @@ namespace ix
ss << "\r\n"; ss << "\r\n";
std::string dest("remove host"); // FIXME
std::cout << ss.str() << std::endl;
if (!writeBytes(ss.str())) if (!writeBytes(ss.str()))
{ {
return WebSocketInitResult(false, 0, std::string("Failed sending response to ") + dest); return WebSocketInitResult(false, 0, std::string("Failed sending response to ") + remote);
} }
setReadyState(OPEN); setReadyState(OPEN);

View File

@ -74,13 +74,10 @@ namespace ix
WebSocketTransport(); WebSocketTransport();
~WebSocketTransport(); ~WebSocketTransport();
// Client void configure(const WebSocketPerMessageDeflateOptions& perMessageDeflateOptions);
void configure(const std::string& url,
const WebSocketPerMessageDeflateOptions& perMessageDeflateOptions);
WebSocketInitResult init();
// Server WebSocketInitResult connectToUrl(const std::string& url); // Client
WebSocketInitResult initFromSocket(int fd); WebSocketInitResult connectToSocket(int fd); // Server
void poll(); void poll();
WebSocketSendInfo sendBinary(const std::string& message); WebSocketSendInfo sendBinary(const std::string& message);