Question about using civet websocket

695 views
Skip to first unread message

William Wang

unread,
Apr 11, 2017, 1:31:39 PM4/11/17
to civetweb
Hi, we have been using civetweb HTTP handler before and we want to add the WebSocket handler recently to our C++ program. I see civetweb-1.9.1 already have support for WebSocket, so I add that to my code and build/run it successfully but I am not able to connect to my server through web socket. I tested with chrome extension 'Simple Web Socket Client', if returns me 'Error during WebSocket handshake: Unexpected response code: 404'. I am not sure what's the problem and I am looking for example how I should use websocket. I didn't override any websocket callback functions, so I assume they will all return true. Here is my code, HttpServer is just a wrapper for CivetServer. Could you help take a look what could be the problem?



    const char * wangwillDemoServerOptions[] = {

        "listening_ports", "9000",

        "num_threads", "16",

        "enable_directory_listing", "no",

        "enable_keep_alive", "yes",

        NULL

    };


    HttpServer * wangwillDemoHttpServer = new HttpServer(wangwillDemoServerOptions);


    WebSocketRequestManager * wangwillWebSocketManager = new WebSocketRequestManager();

    wangwillDemoHttpServer->newWebSocketHandler("/control", wangwillWebSocketManager);

bel

unread,
Apr 11, 2017, 2:28:15 PM4/11/17
to civetweb

What is WebSocketRequestManager?
A class with an implementation of

virtual bool handleData(CivetServer *server,
struct mg_connection *conn,
int bits,
char *data,
size_t data_len);

This is called when the websocket connection receives data.


Currently there is no C++ websocket example code, but there is a C sample code, and the content of the callback functions (overwritten member functions in C++) is the same:

https://github.com/civetweb/civetweb/blob/master/examples/embedded_c/embedded_c.c#L521

William Wang

unread,
Apr 11, 2017, 3:38:07 PM4/11/17
to civetweb
It's an implementation of CivetWebSocketHandler. I did try to overrider this function, but I didn't see any logs because I could not even connect my server through web socket.
I am wondering how can I verify my websocket is up and running, what's the standard process for manual testing? Is there a command line I could use to verify?

BTW: When I do 'telnet host port', I am able to connect to that port. But when I try with the Simple WebSocket Client, I got 404 not found errors.

William Wang

unread,
Apr 11, 2017, 3:49:25 PM4/11/17
to civetweb
And do you mean that it should work even I don't need to override the handleConnection function?
I am thinking should I provide some response back to get the websocket connection open, but sounds like I don't need to worry about that?

William


On Tuesday, April 11, 2017 at 11:28:15 AM UTC-7, bel wrote:

bel

unread,
Apr 11, 2017, 4:22:20 PM4/11/17
to civetweb

I added an example how to use the websocket C++ wrapper:
https://github.com/civetweb/civetweb/blob/master/examples/embedded_cpp/embedded_cpp.cpp
it is tested in Linux (but not yet for Windows).
If you build it, make sure all compile units have "USE_WEBSOCKET" set (for a first test, you might just add #define USE_WEBSOCKET as the first line of civetweb.h and clean and rebuild everything).

Telnet host post works even if websockets are completely disabled, since websocket (ws) and http uses the same port (usually 80 or 8080).
If you type
GET / HTTP/1.0
and press return twice fast enough, you could even get some result.

bel

unread,
Apr 11, 2017, 4:51:04 PM4/11/17
to civetweb


On Tuesday, April 11, 2017 at 9:49:25 PM UTC+2, William Wang wrote:
And do you mean that it should work even I don't need to override the handleConnection function?
I am thinking should I provide some response back to get the websocket connection open, but sounds like I don't need to worry about that?

William


I just tested the example with the unmodified base class:

    CivetWebSocketHandler h_websocket;
    server.addWebSocketHandler("/websocket", h_websocket);

and this works as well. Probably you missed the USE_WEBSOCKET somewhere (it happened to me as well, when I first tried)?

The first debugging tool would be the browser console (of FireFox or Chrome). It will tell you if the connection failed.

William Wang

unread,
Apr 11, 2017, 5:05:24 PM4/11/17
to civetweb
I have two question after checking around your code.

1. Do I need to override the handleGet function as well to make my websocket working?
2.What's the purpose of using USE_WEBSOCKET? Could you help explain a bit more about this? 

Really appreciate your help!
William

bel

unread,
Apr 12, 2017, 3:39:06 PM4/12/17
to civetweb
1) You mean



bool WsStartHandler::handleGet(CivetServer *server, struct mg_connection *conn)


No. This is not strictly required. You need to initiate the websocket connection from the client site. If the client is a browser, it needs some javascript to do this. There are several ways to get this javascript to the client, and handleGet is one of them. A file is another one.


2) USE_WEBSOCKET

This is a #define to activate websocket support in the C and C++ code. If it is set, some additional functions to support websockets are compiled with the code. If it is not set (default), these functions are missing to keep the footprint smaller.

William Wang

unread,
Apr 13, 2017, 5:54:55 PM4/13/17
to civetweb
Thanks a lot, ben.

You are right, it works after I added WITH_WEBSOCKET=1 to my compile script. The websocket is working well so far.
One more problem is that our project also have dependency on openssl which has conflicting definition on SHA1_INIT, SHA1_TRANSFORM. So I updated the function names in src/sha.inl to SHA2_INIT and SHA2_TRANSFORM which feels very hacky to me. 
Do you see any potential impact doing that? Do you have any better ideas how I can resolve these conflicts?

Thanks

bel

unread,
Apr 17, 2017, 2:29:53 PM4/17/17
to civetweb
Since civetweb also uses OpenSSL, it should be the same definition. But it depends what version of OpenSSL you are using.

You could try the following defines:
- OPENSSL_API_1_1 to use OpenSSL 1.1 instead of 1.0
- NO_SSL_DL to open OpenSSL at load time instead of loading it dynamically
- NO_SSL if you do not use SSL with civetweb (no HTTPS or WSS)
Reply all
Reply to author
Forward
0 new messages