Jump to content
FrozenK

Websocket client and server configuration issue

Recommended Posts

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 by FrozenK

Share this post


Link to post

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

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×