FrozenK 0 Posted Friday at 09:30 AM (edited) Hello, I'm trying to configure the most simple websocket client (with TSslWebSocketCli) and server (with TSslHttpAppSrv) in order to get them communicate with each other locally. Worth noting that I'm a beginner in the internet communication protocol world, this is why I'm trying to get the minimum working and then I will build from that. I'm using the ICS 9.0 C++ package, I believe I have a configuration problem more than a C++ problem. For the client part, I configured the following (no TLS for now) : client->SocketFamily = sfAnyIPv4; client->DebugLevel = DebugHdr; client->CertVerMethod = CertVerNone; client->SslCliSecurity = sslCliSecDefault; client->URL = "ws://127.0.0.1/"; client->WSPingSecs = 10; event handlers to get something printed in the terminal : client->OnHttpRestProg = HttpRestProg; client->OnWSFrameRcvd = FrameRcvd; client->OnWSConnected = Connected; client->OnWSDisconnected = Disconnected; For the server part, based on the Delphi samples OverbyteIcsBasicWebServer1.pas and OverbyteIcsSslMultiWebServ.pas, I configured : server->AuthRealm = "ics"; server->SocketErrs = wsErrFriendly; server->ExclusiveAddr = true; server->SessionTimeout = 300; server->MaxSessions = 100; server->OnDisplay = Display; server->SslEnable = false; server->SslCliCertMethod = sslCliCertNone; server->SslCertAutoOrder = false; server->CertExpireDays = 30; server->OcspSrvStapling = false; server->AddGetAllowedPath("/", afBeginBy, "WEB-APP"); server->OnClientConnect = ClientConnect; I added an host : server->IcsHosts->Clear(); TIcsHost *host = new TIcsHost(server->IcsHosts); host->HostEnabled = true; host->HostNames->Text = "localhost"; host->HostTag = "WEB-APP"; host->Descr = "WebApp Server"; host->BindIpAddr = "127.0.0.1"; host->BindNonPort = 80; host->BindSslPort = 0; host->WebDefDoc = "index.html"; host->WebDocDir = dir + "data"; When the client is connecting (TSslWebSocketCli.WSConnect), OnClientConnect is triggered server side, then : THttpWSSrvConn *conn = (THttpWSSrvConn *)Client; conn->WSessionCookie = "OverbyteIcsWebAppServer" + server->Port; conn->OnWSLogEvent = ClientLogEvent; conn->OnWSHandshake = ClientHandShake; conn->OnWSDisconnected = ClientDisconnected; conn->OnWSFrameRcvd = ClientFrameRcvd; conn->OnWSFrameSent = ClientFrameSent; conn->OnWSReady = ClientReady; conn->OnWSPingTimer = ClientPingTimer; conn->OnBgException = ClientBgException; Then the server handle the request (these are called : THttpConnection::ProcessRequest(), ::ProcessGet(), ::ProcessGetHeadDel(), ::SendDocument()...) and returns an "HTTP/1.1 200 OK" response to the client. From TSslWebSocketCli.WSConnect I get "WebSocket: Failed to Connect:" but the LastResponse string is empty. It looks like the server treats my websocket upgrade request as a "classic" request, so it returns an "HTTP/1.1 200 OK" response instead of the expected "HTTP/1.1 101 Switching Protocols". To make sure my client part was ok, I quickly tried it on a node.js websocket server, no problem, I get the "101 Switching Protocols" response and the websocket connection is established. If I do not use TSslWebSocketCli.WSConnect but do a "manual" GET with an upgrade request header and on server side add an url handler (TUrlHandlerIndexHtml) and send a response header through AnswerStream, the connection is established. But if I send frames from the client, OnWSFrameRcvd is not triggred server side (as expected I believe since server has no clue I handled the upgrade "myself"). Hopefully this post makes sense, in short, I don't understand why my upgrade request on url: "ws://127.0.0.1/" fails on the ICS server, any help would be appreciated. Thanks in advance. Edited Friday at 09:54 AM by FrozenK Share this post Link to post
Angus Robertson 577 Posted Friday at 11:27 AM I'd first make the general comment that it is always best to develop and test the two parts of client/server applications separately, against known working versions. In this case, with the ICS OverbyteIcsSslMultiWebServ and OverbyteIcsHttpRestTst samples. Don't know if C++ allows you to build them, but the wiki site allows you to download prebuilt executable files. Your settings are missing a websocket path or page, just ws://127.0.0.1/ so you are assuming the web server default HTML page is actually a Websocket request, this was never testing with the ICS web server, perhaps my fault for not expecting anyone to try that. Since you set default page to index.html, I assume that is the websocket URL you are checking for, but you don;t show any of that code. I find it best to use a virtual path /websocket/ to clarify that such requests from HTML. Angus Share this post Link to post