locked
Websocket Protocol Component C API: How to use to implement a server? RRS feed

  • Question

  • Hi,

    I need some guidance on using the Websocket Protocol Component API to implement a websocket server in C/C++.

    I have already read these:
    1. The MSDN documentation on https://msdn.microsoft.com/en-us/library/windows/desktop/hh437448(v=vs.85).aspx
    2. The sample code on https://code.msdn.microsoft.com/windowsapps/Web-Socket-Protocol-69875c0c
    3. The sample code on https://code.msdn.microsoft.com/windowsdesktop/WinHTTP-WebSocket-sample-50a140b5
    4. Kenny Karr's introduction of the API on https://msdn.microsoft.com/en-us/magazine/jj863133.aspx

    The only thing I understand at this point is that this API is solely meant for parsing websocket requests and computing websocket responses. It has no networking I/O facilities. All users of this API, as I understand, must handle the networking part themselves. Is that correct?

    The MSDN docs refer to something called an "operation queue". What is that? Can someone give a high-level mental model of how the API works (something like the usual "Using the API" section in MSDN docs, but which is missing here), and the role of this "operation queue"?

    Studying the code sample mentioned in point #2 above, my guess on how the API should be used is as follows:

    1. Set up a listening socket and accept incoming connections.

    2. Once an incoming connection is accepted, call WebSocketCreateServerHandle to create a handle named, say, hServer.

    3. Call ::recv(...) on that accepted socket. At this point, how can I use the Websocket Protocol Component API to parse this received data to decide whether it is a client handshake?

    4. Assuming that in step #3 above, I really received a client handshake. The server must now formulate a reply. To do so, this is what I did:
    a) Roll my own code to transform the received client handshake from #3 into an array of WEB_SOCKET_HTTP_HEADERs. 
    b) Pass this array of WEB_SOCKET_HTTP_HEADERs into WebSocketBeginServerHandshake, and viola, it spits out the response that we should send out, in the form of an output array of WEB_SOCKET_HTTP_HEADERs.
    c) However, that array of WEB_SOCKET_HTTP_HEADERs returned by WebSocketBeginServerHandshake cannot be sent out to the client as-is. Again, I have to roll my own code to construct the actual reply to be sent out, by prepending "HTTP/1.1 101 Switching Protocols\r\n", and then appending each of the WEB_SOCKET_HTTP_HEADERs, ending them with "\r\n", and then finally appending a concluding "\r\n".
    d) I sent out the buffer thus computed in c), and the client indeed sees that a the websocket is open, i.e. the handshake has been completed.
    Rolling my own code in steps a) and c) just doesn't feel right - surely the API have some nice facilities to parse the client handshake, and compute the server handshake. Am I using the API correctly?

    5. Now, we've gotten past the handshake, and the client sends some data. How should the server receive it? Studying the code sample mentioned in point #2 above, the way to receive data looks like this:
    a) Call WebSocketReceive(hServer, NULL, NULL) - I am not sure why the sample sets the 2 last parameters as NULL
    b) Call WebSocketGetAction(hServer, WEB_SOCKET_ALL_ACTION_QUEUE, buffers, ...), where buffers is a 2-element WEB_SOCKET_BUFFER array.
    c) The call to WebSocketGetAction in step b) above returns an action type. If this action type is WEB_SOCKET_RECEIVE_FROM_NETWORK_ACTION, then we call ::recv(...) on the accepted socket.
    Is that correct? What's the purpose of calling WebSocketReceive when it actually doesn't do anything - neither actually receive data nor parse some incoming buffer? The actual received data by ::recv(...) might not be a complete frame - does the API do any framing? How do we extract the payload from the recv-ed data?

    Appreciate if anyone can shed light on this. It seems the docs is missing a crucial overview which explains how the API hangs together, rather than just presenting function descriptions.

    Thursday, February 26, 2015 9:09 AM

All replies

  • I've been searching the web for weeks trying to figure out this WebSocket Protocol Component API.  I found this question from cacaommm from a few years ago and I basically have the same issues/questions. 

    I'm trying to build a WebSocket server using this API.  I've done all the handshaking and I have a websocket connection that looks to be up and running.  I have confirmed (via wireshark) that I can send data from a client to my server over the websocket, however, I don't know how to 'read' the data from the websocket on the server side.  cacaommm mentions above to call recv(...), but isn't that call for a normal socket, not a websocket? (ie. it takes a socket handle, not a websocket handle).   

    The sample code that comes with the API uses some 'transport' class and in the header file it states:

    // Abstract transport that allows writing and reading data. The goal here was to simplify sample's code,
    // so it does not have to take into the account all complications associated with using sockets or pipes.
    // However, it should be straightforward to replace this abstract transport with a concrete one list sockets/pipes/etc.

    I have little to no experience with sockets so I'm struggling with how to read this data from the websocket.  Can someone please help?  Was cacaommm's original question ever answered?  cacaommm did you ever figure this out?

    Thanks in advance!

    Wednesday, July 24, 2019 7:43 PM