- Added class signalr_client_config which holds http_client_config and websocket_client_config
- Removed (hub_)connection::set_headers and replaced it with set_client_config
Since SignalR payloads are Json we parse the incoming message as a Json object and extract the actual message. For persistent connections the api is a string based so we need to turn the message back to string. We used to always serialize it but if the value is already a string it causes double escaping. The fix is to check if the value is a string and if it is just pass it down to the receive handler, otherwise (e.g. it is a json object or a number etc.) we serialize it back to string as we did before.
Issue: #128
There was a race between sending the last progress message and returning from the hub method and the server does not serve the progress message if the method has already completed. Sleeping after reporting progress "fixes" the race.
If the user called `stop()` before the init message (the response to the /connect request) was received and the init message was not received within the `TransportConnectTimeout` we would have thrown an exception saying "transport timed out when trying to connect". This is unexpected since the user had already called `.stop()` on the connection. The issue was that in the thread that was terminating the `start()` request in case of connect timeout we did not check if the connection hadn't been stopped. After the change, if the connection had been stopped we just complete the `connect_request_tce` and let the continuation to take care of the rest (which results in throwing pplx::task_canceled exception since the `start()` was cancelled by invoking the `stop()` function).
Bonus: removing the test that tests that the transport is being stopped if the instance goes out of scope without first `disconnect()`ing first. This test is flakey and there is no good way of making it more reliable. The `websocket_transport` class is meant to only be used internally and we always `disconnect()` the transport when the connection is being stopped.
Note: cpprestsdk moved to shipping multiple smaller packages for different platforms so renamed SignalR package to reflect this. We would most likely adopt this model as well.
When we stop a connection we just signal that the transport should be stopped but don't wait for it to actually stop. If then the same connection is immediately started the old transport can still be running. Because the callbacks are not reset when stopping the transport errors and messages from the old transport can still invoke them on the newly started connection. This is especially harmful in case of errors because they would cause reconnects. The fix is to ignore any message or error received from a transport started by a connection that has already been stopped.
Previously to prevent the user from deadlocking themselves in case the called `connection.stop()` from the `reconnecting` event we would first start the reconnecting process and then called the `reconnecting` event. This was racey since it was (very unlikely but still) possible that reconnect would finish quickly and would invoke `reconnected` callback before the `reconnecting` callback was invoked (happens once in a blue moon on a @BrennanConroy 's box). Another issue was that if the user called `connection.stop()` and `connection.start()` in the event the connection could be dropped so we would start a new reconnect attempt and as a result we would have 2 reconnecting attempts running in parallel but using the same disconnect cts and start event. The fix is to invoke the `reconnecting` event before starting the reconnecting process. We also copy the current disconnect cts which makes it possible to check if the connection was restarted in the `reconnecting` callback and if it was we are canceling this reconnect. This makes it impossible to have multiple concurrent reconnects.
`trace_log_writer` is the default log writer which (for windows) is using `OutputDebugString` to log the client activity. It was only public because it was used as the default parameter value for `log_writer` in the ctors of the `connection` and `hub_connection` classes. This class was not really meant to be used externally (and after one of the previous changes it could not even be used externally because the `write` method was not exported from the dll) so I am moving it from the public includes folder into the implementation folder.