Deployed fa0408e with MkDocs version: 1.1.2

This commit is contained in:
2020-10-08 19:44:07 +00:00
parent 5d11fd38c8
commit e2d346e9dd
11 changed files with 50 additions and 93 deletions

View File

@ -98,6 +98,10 @@
<li class="nav-item" data-level="1"><a href="#changelog" class="nav-link">Changelog</a>
<ul class="nav flex-column">
<li class="nav-item" data-level="2"><a href="#1050-2020-09-30" class="nav-link">[10.5.0] - 2020-09-30</a>
<ul class="nav flex-column">
</ul>
</li>
<li class="nav-item" data-level="2"><a href="#1049-2020-09-30" class="nav-link">[10.4.9] - 2020-09-30</a>
<ul class="nav flex-column">
</ul>
@ -1047,6 +1051,8 @@
<h1 id="changelog">Changelog</h1>
<p>All changes to this project will be documented in this file.</p>
<h2 id="1050-2020-09-30">[10.5.0] - 2020-09-30</h2>
<p>(http client + server + ws) Add support for uploading files with ws -F foo=@filename, new -D http server option to debug incoming client requests, internal api changed for http POST, PUT and PATCH to supply an HttpFormDataParameters</p>
<h2 id="1049-2020-09-30">[10.4.9] - 2020-09-30</h2>
<p>(http server + utility code) Add support for doing gzip compression with libdeflate library, if available</p>
<h2 id="1048-2020-09-30">[10.4.8] - 2020-09-30</h2>
@ -1321,7 +1327,6 @@ ws_connect: connection closed: code 1000 reason Normal closure
[2020-03-17 23:53:19.502] [info] Received 208 bytes
[2020-03-17 23:53:19.502] [info] Sent 0 bytes
</code></pre>
<h2 id="826-2020-03-16">[8.2.6] - 2020-03-16</h2>
<p>(cobra to sentry bot + docker) default docker file uses mbedtls + ws cobra_to_sentry pass tls options to sentryClient.</p>
<h2 id="825-2020-03-13">[8.2.5] - 2020-03-13</h2>
@ -1432,11 +1437,9 @@ ws_connect: connection closed: code 1000 reason Normal closure
<p>Before:</p>
<pre><code>Connection error: Got bad status connecting to example.com:443, status: 200, HTTP Status line: HTTP/1.1 200 OK
</code></pre>
<p>After:</p>
<pre><code>Connection error: Expecting status 101 (Switching Protocol), got 200 status connecting to example.com:443, HTTP Status line: HTTP/1.1 200 OK
</code></pre>
<h2 id="753-2019-12-12">[7.5.3] - 2019-12-12</h2>
<p>(server) attempt at fixing #131 by using blocking writes in server mode</p>
<h2 id="752-2019-12-11">[7.5.2] - 2019-12-11</h2>
@ -1467,7 +1470,6 @@ ws_connect: connection closed: code 1000 reason Normal closure
[2019-12-05 15:50:44.763] [info] messages received 18839 sent 25
[2019-12-05 15:50:45.768] [info] messages received 18839 sent 25
</code></pre>
<h2 id="745-2019-12-03">[7.4.5] - 2019-12-03</h2>
<ul>
<li>(ws) #125 / fix build problem when jsoncpp is not installed locally</li>
@ -1559,7 +1561,6 @@ ws_connect: connection closed: code 1000 reason Normal closure
</ul>
<pre><code>ws httpd -L --redirect_url https://www.google.com
</code></pre>
<h2 id="627-2019-09-25">[6.2.7] - 2019-09-25</h2>
<ul>
<li>Stop having ws send subcommand send a binary message in text mode, which would cause error in <code>make ws_test</code> shell script test.</li>
@ -1663,7 +1664,6 @@ ws_connect: connection closed: code 1000 reason Normal closure
</ul>
<pre><code>ws connect --max_wait 5000 ws://example.com # will only wait 5 seconds max between reconnection attempts
</code></pre>
<h2 id="507-2019-08-23">[5.0.7] - 2019-08-23</h2>
<ul>
<li>WebSocket: add new option to pass in extra HTTP headers when connecting.</li>
@ -1672,7 +1672,6 @@ ws_connect: connection closed: code 1000 reason Normal closure
<p>If you run against <code>ws echo_server</code> you will see the headers being received printed in the terminal.</p>
<pre><code>ws connect -H &quot;foo: bar&quot; -H &quot;baz: buz&quot; ws://127.0.0.1:8008
</code></pre>
<ul>
<li>CobraConnection: sets a unique id field for all messages sent to <a href="https://github.com/machinezone/cobra">cobra</a>.</li>
<li>CobraConnection: sets a counter as a field for each event published.</li>

View File

@ -114,7 +114,6 @@ cmake -DUSE_TLS=1 ..
make -j
make install # will install to /usr/local on Unix, on macOS it is a good idea to sudo chown -R `whoami`:staff /usr/local
</code></pre>
<p>Headers and a static library will be installed to the target dir.
There is a unittest which can be executed by typing <code>make test</code>.</p>
<p>Options for building:</p>
@ -135,14 +134,12 @@ There is a unittest which can be executed by typing <code>make test</code>.</p>
...
)
</code></pre>
<h3 id="vcpkg">vcpkg</h3>
<p>It is possible to get IXWebSocket through Microsoft <a href="https://github.com/microsoft/vcpkg">vcpkg</a>.</p>
<pre><code>vcpkg install ixwebsocket
</code></pre>
<p>To use the installed package within a cmake project, use the following:</p>
<pre><code class="cmake"> set(CMAKE_TOOLCHAIN_FILE &quot;$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake&quot; CACHE STRING &quot;&quot;) # this is super important in order for cmake to include the vcpkg search/lib paths!
<pre><code class="language-cmake"> set(CMAKE_TOOLCHAIN_FILE &quot;$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake&quot; CACHE STRING &quot;&quot;) # this is super important in order for cmake to include the vcpkg search/lib paths!
# find library and its headers
find_path(IXWEBSOCKET_INCLUDE_DIR ixwebsocket/IXWebSocket.h)
@ -153,7 +150,6 @@ There is a unittest which can be executed by typing <code>make test</code>.</p>
target_link_libraries(${PROJECT_NAME} ... ${IXWEBSOCKET_LIBRARY}) # Cmake will automatically fail the generation if the lib was not found, i.e is set to NOTFOUNS
</code></pre>
<h3 id="conan">Conan</h3>
<p><a href="https://bintray.com/conan/conan-center/ixwebsocket%3A_/_latestVersion"> <img alt="Download" src="https://api.bintray.com/packages/conan/conan-center/ixwebsocket%3A_/images/download.svg" /> </a></p>
<p>Conan is currently supported through a recipe in <a href="https://github.com/conan-io/conan-center-index/tree/master/recipes/ixwebsocket">Conan Center</a> (<a href="https://bintray.com/conan/conan-center/ixwebsocket%3A_">Bintray entry</a>).</p>
@ -167,7 +163,6 @@ There is a unittest which can be executed by typing <code>make test</code>.</p>
<p>There is a Dockerfile for running the unittest on Linux, and to run the <code>ws</code> tool. It is also available on the docker registry.</p>
<pre><code>docker run docker.pkg.github.com/machinezone/ixwebsocket/ws:latest --help
</code></pre>
<p>To use docker-compose you must make a docker container first.</p>
<pre><code>$ make docker
...

View File

@ -110,7 +110,7 @@
<p>Bring up 3 terminals and run a server, a publisher and a subscriber in each one. As you publish data you should see it being received by the subscriber. You can run <code>redis-cli MONITOR</code> too to see how redis is being used.</p>
<h3 id="server">Server</h3>
<p>You will need to have a redis server running locally. To run the server:</p>
<pre><code class="bash">$ cd &lt;ixwebsocket-top-level-folder&gt;/ixsnake/ixsnake
<pre><code class="language-bash">$ cd &lt;ixwebsocket-top-level-folder&gt;/ixsnake/ixsnake
$ ws snake
{
&quot;apps&quot;: {
@ -131,9 +131,8 @@ redis host: 127.0.0.1
redis password:
redis port: 6379
</code></pre>
<h3 id="publisher">Publisher</h3>
<pre><code class="bash">$ cd &lt;ixwebsocket-top-level-folder&gt;/ws
<pre><code class="language-bash">$ cd &lt;ixwebsocket-top-level-folder&gt;/ws
$ ws cobra_publish --appkey FC2F10139A2BAc53BB72D9db967b024f --endpoint ws://127.0.0.1:8008 --rolename _pub --rolesecret 1c04DB8fFe76A4EeFE3E318C72d771db test_channel cobraMetricsSample.json
[2019-11-27 09:06:12.980] [info] Publisher connected
[2019-11-27 09:06:12.980] [info] Connection: Upgrade
@ -145,9 +144,8 @@ $ ws cobra_publish --appkey FC2F10139A2BAc53BB72D9db967b024f --endpoint ws://127
[2019-11-27 09:06:12.982] [info] Published msg 3
[2019-11-27 09:06:12.982] [info] Published message id 3 acked
</code></pre>
<h3 id="subscriber">Subscriber</h3>
<pre><code class="bash">$ ws cobra_subscribe --appkey FC2F10139A2BAc53BB72D9db967b024f --endpoint ws://127.0.0.1:8008 --rolename _pub --rolesecret 1c04DB8fFe76A4EeFE3E318C72d771db test_channel
<pre><code class="language-bash">$ ws cobra_subscribe --appkey FC2F10139A2BAc53BB72D9db967b024f --endpoint ws://127.0.0.1:8008 --rolename _pub --rolesecret 1c04DB8fFe76A4EeFE3E318C72d771db test_channel
#messages 0 msg/s 0
[2019-11-27 09:07:39.341] [info] Subscriber connected
[2019-11-27 09:07:39.341] [info] Connection: Upgrade

View File

@ -136,7 +136,7 @@
<li>FreeBSD</li>
</ul>
<h2 id="example-code">Example code</h2>
<pre><code class="c++">// Required on Windows
<pre><code class="language-c++">// Required on Windows
ix::initNetSystem();
// Our websocket object
@ -161,7 +161,6 @@ webSocket.start();
// Send a message to the server (default to TEXT mode)
webSocket.send(&quot;hello world&quot;);
</code></pre>
<h2 id="why-another-library">Why another library?</h2>
<p>There are 2 main reasons that explain why IXWebSocket got written. First, we needed a C++ cross-platform client library, which should have few dependencies. What looked like the most solid one, <a href="https://github.com/zaphoyd/websocketpp">websocketpp</a> did depend on boost and this was not an option for us. Secondly, there were other available libraries with fewer dependencies (C ones), but they required calling an explicit poll routine periodically to know if a client had received data from a server, which was not elegant.</p>
<p>We started by solving those 2 problems, then we added server websocket code, then an HTTP client, and finally a very simple HTTP server. IXWebSocket comes with a command line utility named ws which is quite handy, and is now packaged with alpine linux. You can install it with <code>apk add ws</code>.</p>
@ -265,5 +264,5 @@ webSocket.send(&quot;hello world&quot;);
<!--
MkDocs version : 1.1.2
Build Date UTC : 2020-09-30 21:35:01.038353+00:00
Build Date UTC : 2020-10-08 19:44:07.118071+00:00
-->

View File

@ -115,7 +115,6 @@
/tmp$ openssl sha512 v9.1.9.tar.gz
SHA512(v9.1.9.tar.gz)= f1fd731b5f6a9ce6d6d10bee22a5d9d9baaa8ea0564d6c4cd7eb91dcb88a45c49b2c7fdb75f8640a3589c1b30cee33ef5df8dcbb55920d013394d1e33ddd3c8e
</code></pre>
<p>Now go punch those values in the vcpkg ixwebsocket port config files. Here is what the diff look like.</p>
<pre><code>vcpkg$ git diff
diff --git a/ports/ixwebsocket/CONTROL b/ports/ixwebsocket/CONTROL
@ -143,14 +142,12 @@ index de082aece..68e523a05 100644
+ SHA512 f1fd731b5f6a9ce6d6d10bee22a5d9d9baaa8ea0564d6c4cd7eb91dcb88a45c49b2c7fdb75f8640a3589c1b30cee33ef5df8dcbb55920d013394d1e33ddd3c8e
)
</code></pre>
<p>You will need a fork of the vcpkg repo to make a pull request.</p>
<pre><code>git fetch upstream
git co master
git reset --hard upstream/master
git push origin master --force
</code></pre>
<p>Make the pull request (I use a new branch to do that).</p>
<pre><code>vcpkg$ git co -b feature/ixwebsocket_9.1.9
M ports/ixwebsocket/CONTROL
@ -186,7 +183,6 @@ To https://github.com/bsergean/vcpkg.git
Branch 'feature/ixwebsocket_9.1.9' set up to track remote branch 'feature/ixwebsocket_9.1.9' from 'origin' by rebasing.
vcpkg$
</code></pre>
<p>Just visit this url, https://github.com/bsergean/vcpkg/pull/new/feature/ixwebsocket_9.1.9, printed on the console, to make the pull request.</p></div>
</div>
</div>

View File

@ -111,7 +111,6 @@
<p>By using the push_server ws sub-command, the server will send the same message in a loop to any connected client.</p>
<pre><code>ws push_server -q --send_msg 'yo'
</code></pre>
<p>By using the echo_client ws sub-command, with the -m (mute or no_send), we will display statistics on how many messages we can receive per second.</p>
<pre><code>$ ws echo_client -m ws://localhost:8008
[2020-08-02 12:31:17.284] [info] ws_echo_client: connected

File diff suppressed because one or more lines are too long

View File

@ -1,39 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"><url>
<loc>None</loc>
<lastmod>2020-09-30</lastmod>
<lastmod>2020-10-08</lastmod>
<changefreq>daily</changefreq>
</url><url>
<loc>None</loc>
<lastmod>2020-09-30</lastmod>
<lastmod>2020-10-08</lastmod>
<changefreq>daily</changefreq>
</url><url>
<loc>None</loc>
<lastmod>2020-09-30</lastmod>
<lastmod>2020-10-08</lastmod>
<changefreq>daily</changefreq>
</url><url>
<loc>None</loc>
<lastmod>2020-09-30</lastmod>
<lastmod>2020-10-08</lastmod>
<changefreq>daily</changefreq>
</url><url>
<loc>None</loc>
<lastmod>2020-09-30</lastmod>
<lastmod>2020-10-08</lastmod>
<changefreq>daily</changefreq>
</url><url>
<loc>None</loc>
<lastmod>2020-09-30</lastmod>
<lastmod>2020-10-08</lastmod>
<changefreq>daily</changefreq>
</url><url>
<loc>None</loc>
<lastmod>2020-09-30</lastmod>
<lastmod>2020-10-08</lastmod>
<changefreq>daily</changefreq>
</url><url>
<loc>None</loc>
<lastmod>2020-09-30</lastmod>
<lastmod>2020-10-08</lastmod>
<changefreq>daily</changefreq>
</url><url>
<loc>None</loc>
<lastmod>2020-09-30</lastmod>
<lastmod>2020-10-08</lastmod>
<changefreq>daily</changefreq>
</url>
</urlset>

Binary file not shown.

View File

@ -133,7 +133,7 @@
<p>The <a href="https://github.com/machinezone/IXWebSocket/tree/master/ws"><em>ws</em></a> folder countains many interactive programs for chat, <a href="https://github.com/machinezone/IXWebSocket/blob/master/ws/ws_send.cpp">file transfers</a>, <a href="https://github.com/machinezone/IXWebSocket/blob/master/ws/ws_http_client.cpp">curl like</a> http clients, demonstrating client and server usage.</p>
<h2 id="windows-note">Windows note</h2>
<p>To use the network system on Windows, you need to initialize it once with <em>WSAStartup()</em> and clean it up with <em>WSACleanup()</em>. We have helpers for that which you can use, see below. This init would typically take place in your main function.</p>
<pre><code class="cpp">#include &lt;ixwebsocket/IXNetSystem.h&gt;
<pre><code class="language-cpp">#include &lt;ixwebsocket/IXNetSystem.h&gt;
int main()
{
@ -145,9 +145,8 @@ int main()
return 0;
}
</code></pre>
<h2 id="websocket-client-api">WebSocket client API</h2>
<pre><code class="cpp">#include &lt;ixwebsocket/IXWebSocket.h&gt;
<pre><code class="language-cpp">#include &lt;ixwebsocket/IXWebSocket.h&gt;
...
@ -188,7 +187,6 @@ webSocket.sendBinary(&quot;some serialized binary data&quot;);
// Stop the connection
webSocket.stop()
</code></pre>
<h3 id="sending-messages">Sending messages</h3>
<p><code>WebSocketSendInfo result = websocket.send("foo")</code> will send a message.</p>
<p>If the connection was closed, sending will fail, and the success field of the result object will be set to false. There could also be a compression error in which case the compressError field will be set to true. The payloadSize field and wireSize fields will tell you respectively how much bytes the message weight, and how many bytes were sent on the wire (potentially compressed + counting the message header (a few bytes).</p>
@ -207,7 +205,6 @@ webSocket.stop()
return _connected;
});
</code></pre>
<h3 id="readystate">ReadyState</h3>
<p><code>getReadyState()</code> returns the state of the connection. There are 4 possible states.</p>
<ol>
@ -218,7 +215,7 @@ webSocket.stop()
</ol>
<h3 id="open-and-close-notifications">Open and Close notifications</h3>
<p>The onMessage event will be fired when the connection is opened or closed. This is similar to the <a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSocket">JavaScript browser API</a>, which has <code>open</code> and <code>close</code> events notification that can be registered with the browser <code>addEventListener</code>.</p>
<pre><code class="cpp">webSocket.setOnMessageCallback([](const ix::WebSocketMessagePtr&amp; msg)
<pre><code class="language-cpp">webSocket.setOnMessageCallback([](const ix::WebSocketMessagePtr&amp; msg)
{
if (msg-&gt;type == ix::WebSocketMessageType::Open)
{
@ -243,10 +240,9 @@ webSocket.stop()
}
);
</code></pre>
<h3 id="error-notification">Error notification</h3>
<p>A message will be fired when there is an error with the connection. The message type will be <code>ix::WebSocketMessageType::Error</code>. Multiple fields will be available on the event to describe the error.</p>
<pre><code class="cpp">webSocket.setOnMessageCallback([](const ix::WebSocketMessagePtr&amp; msg)
<pre><code class="language-cpp">webSocket.setOnMessageCallback([](const ix::WebSocketMessagePtr&amp; msg)
{
if (msg-&gt;type == ix::WebSocketMessageType::Error)
{
@ -260,7 +256,6 @@ webSocket.stop()
}
);
</code></pre>
<h3 id="start-stop">start, stop</h3>
<ol>
<li><code>websocket.start()</code> connect to the remote server and starts the message receiving background thread.</li>
@ -268,13 +263,12 @@ webSocket.stop()
</ol>
<h3 id="configuring-the-remote-url">Configuring the remote url</h3>
<p>The url can be set and queried after a websocket object has been created. You will have to call <code>stop</code> and <code>start</code> if you want to disconnect and connect to that new url.</p>
<pre><code class="cpp">std::string url(&quot;wss://example.com&quot;);
<pre><code class="language-cpp">std::string url(&quot;wss://example.com&quot;);
websocket.configure(url);
</code></pre>
<h3 id="pingpong-support">Ping/Pong support</h3>
<p>Ping/pong messages are used to implement keep-alive. 2 message types exists to identify ping and pong messages. Note that when a ping message is received, a pong is instantly send back as requested by the WebSocket spec.</p>
<pre><code class="cpp">webSocket.setOnMessageCallback([](const ix::WebSocketMessagePtr&amp; msg)
<pre><code class="language-cpp">webSocket.setOnMessageCallback([](const ix::WebSocketMessagePtr&amp; msg)
{
if (msg-&gt;type == ix::WebSocketMessageType::Ping ||
msg-&gt;type == ix::WebSocketMessageType::Pong)
@ -284,42 +278,35 @@ websocket.configure(url);
}
);
</code></pre>
<p>A ping message can be sent to the server, with an optional data string.</p>
<pre><code class="cpp">websocket.ping(&quot;ping data, optional (empty string is ok): limited to 125 bytes long&quot;);
<pre><code class="language-cpp">websocket.ping(&quot;ping data, optional (empty string is ok): limited to 125 bytes long&quot;);
</code></pre>
<h3 id="heartbeat">Heartbeat.</h3>
<p>You can configure an optional heart beat / keep-alive, sent every 45 seconds
when there is no any traffic to make sure that load balancers do not kill an
idle connection.</p>
<pre><code class="cpp">webSocket.setPingInterval(45);
<pre><code class="language-cpp">webSocket.setPingInterval(45);
</code></pre>
<h3 id="supply-extra-http-headers">Supply extra HTTP headers.</h3>
<p>You can set extra HTTP headers to be sent during the WebSocket handshake.</p>
<pre><code class="cpp">WebSocketHttpHeaders headers;
<pre><code class="language-cpp">WebSocketHttpHeaders headers;
headers[&quot;foo&quot;] = &quot;bar&quot;;
webSocket.setExtraHeaders(headers);
</code></pre>
<h3 id="subprotocols">Subprotocols</h3>
<p>You can specify subprotocols to be set during the WebSocket handshake. For more info you can refer to <a href="https://hpbn.co/websocket/#subprotocol-negotiation">this doc</a>.</p>
<pre><code class="cpp">webSocket.addSubprotocol(&quot;appProtocol-v1&quot;);
<pre><code class="language-cpp">webSocket.addSubprotocol(&quot;appProtocol-v1&quot;);
webSocket.addSubprotocol(&quot;appProtocol-v2&quot;);
</code></pre>
<p>The protocol that the server did accept is available in the open info <code>protocol</code> field.</p>
<pre><code class="cpp">std::cout &lt;&lt; &quot;protocol: &quot; &lt;&lt; msg-&gt;openInfo.protocol &lt;&lt; std::endl;
<pre><code class="language-cpp">std::cout &lt;&lt; &quot;protocol: &quot; &lt;&lt; msg-&gt;openInfo.protocol &lt;&lt; std::endl;
</code></pre>
<h3 id="automatic-reconnection">Automatic reconnection</h3>
<p>Automatic reconnection kicks in when the connection is disconnected without the user consent. This feature is on by default and can be turned off.</p>
<pre><code class="cpp">webSocket.enableAutomaticReconnection(); // turn on
<pre><code class="language-cpp">webSocket.enableAutomaticReconnection(); // turn on
webSocket.disableAutomaticReconnection(); // turn off
bool enabled = webSocket.isAutomaticReconnectionEnabled(); // query state
</code></pre>
<p>The technique to calculate wait time is called <a href="https://docs.aws.amazon.com/general/latest/gr/api-retries.html">exponential
backoff</a>. Here
are the default waiting times between attempts (from connecting with <code>ws connect ws://foo.com</code>)</p>
@ -342,16 +329,14 @@ Wait time(ms): 6400
#retries: 8
Wait time(ms): 10000
</code></pre>
<p>The waiting time is capped by default at 10s between 2 attempts, but that value can be changed and queried.</p>
<pre><code class="cpp">webSocket.setMaxWaitBetweenReconnectionRetries(5 * 1000); // 5000ms = 5s
<pre><code class="language-cpp">webSocket.setMaxWaitBetweenReconnectionRetries(5 * 1000); // 5000ms = 5s
uint32_t m = webSocket.getMaxWaitBetweenReconnectionRetries();
</code></pre>
<h2 id="websocket-server-api">WebSocket server API</h2>
<h3 id="legacy-api">Legacy api</h3>
<p>This api was actually changed to take a weak_ptr<WebSocket> as the first argument to setOnConnectionCallback ; previously it would take a shared_ptr<WebSocket> which was creating cycles and then memory leaks problems.</p>
<pre><code class="cpp">#include &lt;ixwebsocket/IXWebSocketServer.h&gt;
<pre><code class="language-cpp">#include &lt;ixwebsocket/IXWebSocketServer.h&gt;
...
@ -422,11 +407,10 @@ server.start();
server.wait();
</code></pre>
<h3 id="new-api">New api</h3>
<p>The new API does not require to use 2 nested callbacks, which is a bit annoying. The real fix is that there was a memory leak due to a shared_ptr cycle, due to passing down a shared_ptr<WebSocket> down to the callbacks.</p>
<p>The webSocket reference is guaranteed to be always valid ; by design the callback will never be invoked with a null webSocket object.</p>
<pre><code class="cpp">#include &lt;ixwebsocket/IXWebSocketServer.h&gt;
<pre><code class="language-cpp">#include &lt;ixwebsocket/IXWebSocketServer.h&gt;
...
@ -485,9 +469,8 @@ server.start();
server.wait();
</code></pre>
<h2 id="http-client-api">HTTP client API</h2>
<pre><code class="cpp">#include &lt;ixwebsocket/IXHttpClient.h&gt;
<pre><code class="language-cpp">#include &lt;ixwebsocket/IXHttpClient.h&gt;
...
@ -533,11 +516,18 @@ out = httpClient.get(url, args);
// POST request with parameters
HttpParameters httpParameters;
httpParameters[&quot;foo&quot;] = &quot;bar&quot;;
out = httpClient.post(url, httpParameters, args);
// HTTP form data can be passed in as well, for multi-part upload of files
HttpFormDataParameters httpFormDataParameters;
httpParameters[&quot;baz&quot;] = &quot;booz&quot;;
out = httpClient.post(url, httpParameters, httpFormDataParameters, args);
// POST request with a body
out = httpClient.post(url, std::string(&quot;foo=bar&quot;), args);
// PUT and PATCH are available too.
//
// Result
//
@ -566,10 +556,9 @@ bool ok = httpClient.performRequest(args, [](const HttpResponsePtr&amp; response
// ok will be false if your httpClient is not async
</code></pre>
<p>See this <a href="https://github.com/machinezone/IXWebSocket/issues/209">issue</a> for links about uploading files with HTTP multipart.</p>
<h2 id="http-server-api">HTTP server API</h2>
<pre><code class="cpp">#include &lt;ixwebsocket/IXHttpServer.h&gt;
<pre><code class="language-cpp">#include &lt;ixwebsocket/IXHttpServer.h&gt;
ix::HttpServer server(port, hostname);
@ -583,9 +572,8 @@ if (!res.first)
server.start();
server.wait();
</code></pre>
<p>If you want to handle how requests are processed, implement the setOnConnectionCallback callback, which takes an HttpRequestPtr as input, and returns an HttpResponsePtr. You can look at HttpServer::setDefaultConnectionCallback for a slightly more advanced callback example.</p>
<pre><code class="cpp">setOnConnectionCallback(
<pre><code class="language-cpp">setOnConnectionCallback(
[this](HttpRequestPtr request,
std::shared_ptr&lt;ConnectionState&gt; connectionState) -&gt; HttpResponsePtr
{
@ -605,21 +593,19 @@ server.wait();
content);
}
</code></pre>
<h2 id="tls-support-and-configuration">TLS support and configuration</h2>
<p>To leverage TLS features, the library must be compiled with the option <code>USE_TLS=1</code>.</p>
<p>If you are using OpenSSL, try to be on a version higher than 1.1.x as there there are thread safety problems with 1.0.x.</p>
<p>Then, secure sockets are automatically used when connecting to a <code>wss://*</code> url.</p>
<p>Additional TLS options can be configured by passing a <code>ix::SocketTLSOptions</code> instance to the
<code>setTLSOptions</code> on <code>ix::WebSocket</code> (or <code>ix::WebSocketServer</code> or <code>ix::HttpServer</code>)</p>
<pre><code class="cpp">webSocket.setTLSOptions({
<pre><code class="language-cpp">webSocket.setTLSOptions({
.certFile = &quot;path/to/cert/file.pem&quot;,
.keyFile = &quot;path/to/key/file.pem&quot;,
.caFile = &quot;path/to/trust/bundle/file.pem&quot;, // as a file, or in memory buffer in PEM format
.tls = true // required in server mode
});
</code></pre>
<p>Specifying <code>certFile</code> and <code>keyFile</code> configures the certificate that will be used to communicate with TLS peers.</p>
<p>On a client, this is only necessary for connecting to servers that require a client certificate.</p>
<p>On a server, this is necessary for TLS support.</p>

View File

@ -162,7 +162,6 @@ Subcommands:
snake Snake server
httpd HTTP server
</code></pre>
<h2 id="curl">curl</h2>
<p>The curl subcommand try to be compatible with the curl syntax, to fetch http pages.</p>
<p>Making a HEAD request with the -I parameter.</p>
@ -185,7 +184,6 @@ Upload size: 143
Download size: 0
Status: 200
</code></pre>
<p>Making a POST request with the -F parameter.</p>
<pre><code>$ ws curl -F foo=bar https://httpbin.org/post
foo: bar
@ -224,7 +222,6 @@ payload: {
&quot;url&quot;: &quot;https://httpbin.org/post&quot;
}
</code></pre>
<p>Passing in a custom header with -H.</p>
<pre><code>$ ws curl -F foo=bar -H 'my_custom_header: baz' https://httpbin.org/post
my_custom_header: baz
@ -265,7 +262,6 @@ payload: {
&quot;url&quot;: &quot;https://httpbin.org/post&quot;
}
</code></pre>
<h2 id="connect">connect</h2>
<p>The connect command connects to a websocket endpoint, and starts an interactive prompt. Line editing, such as using the direction keys to fetch the last thing you tried to type) is provided. That command is pretty useful to try to send random data to an endpoint and verify that the service handles it with grace (such as sending invalid json).</p>
<pre><code>ws connect wss://echo.websocket.org
@ -290,7 +286,6 @@ ws_connect: received message: Hello world !
&gt; Received 13 bytes
ws_connect: received message: Hello world !
</code></pre>
<pre><code>ws connect 'ws://jeanserge.com/v2?appkey=_pubsub'
Type Ctrl-D to exit prompt...
Connecting to url: ws://jeanserge.com/v2?appkey=_pubsub
@ -316,27 +311,23 @@ Sec-WebSocket-Extensions: permessage-deflate; server_max_window_bits=15; client_
Server: Python/3.7 websockets/8.0.2
Upgrade: websocket
</code></pre>
<h2 id="websocket-proxy">Websocket proxy</h2>
<pre><code>ws proxy_server --remote_host ws://127.0.0.1:9000 -v
Listening on 127.0.0.1:8008
</code></pre>
<p>If you connect to ws://127.0.0.1:8008, the proxy will connect to ws://127.0.0.1:9000 and pass all traffic to this server.</p>
<p>You can also use a more complex setup if you want to redirect to different websocket servers based on the hostname your client is trying to connect to. If you have multiple CNAME aliases that point to the same server.</p>
<p>A JSON config file is used to express that mapping ; here connecting to echo.jeanserge.com will proxy the client to ws://localhost:8008 on the local machine (which actually runs ws echo_server), while connecting to bavarde.jeanserge.com will proxy the client to ws://localhost:5678 where a cobra python server is running. As a side note you will need a wildcard SSL certificate if you want to have SSL enabled on that machine.</p>
<pre><code class="json">{
<pre><code class="language-json">{
&quot;remote_urls&quot;: {
&quot;echo.jeanserge.com&quot;: &quot;ws://localhost:8008&quot;,
&quot;bavarde.jeanserge.com&quot;: &quot;ws://localhost:5678&quot;
}
}
</code></pre>
<p>The --config_path option is required to instruct ws proxy_server to read that file.</p>
<pre><code>ws proxy_server --config_path proxyConfig.json --port 8765
</code></pre>
<h2 id="file-transfer">File transfer</h2>
<pre><code># Start transfer server, which is just a broadcast server at this point
ws transfer # running on port 8080.
@ -347,7 +338,6 @@ ws receive ws://localhost:8080
# Then send a file. File will be received and written to disk by the receiver process
ws send ws://localhost:8080 /file/to/path
</code></pre>
<h2 id="http-client">HTTP Client</h2>
<pre><code>$ ws curl --help
HTTP Client
@ -371,7 +361,6 @@ Options:
--connect-timeout INT Connection timeout
--transfer-timeout INT Transfer timeout
</code></pre>
<h2 id="cobra-client-and-server">Cobra client and server</h2>
<p><a href="https://github.com/machinezone/cobra">cobra</a> is a real time messenging server. ws has several sub-command to interact with cobra. There is also a minimal cobra compatible server named snake available.</p>
<p>Below are examples on running a snake server and clients with TLS enabled (the server only works with the OpenSSL and the Mbed TLS backend for now).</p>
@ -428,7 +417,6 @@ subject=/O=machinezone/O=IXWebSocket/CN=selfsigned-client
Getting Private key
generated ./.certs/selfsigned-client-crt.pem
</code></pre>
<p>Now run the snake server.</p>
<pre><code>$ export certs=.certs
$ ws snake --tls --port 8765 --cert-file ${certs}/trusted-server-crt.pem --key-file ${certs}/trusted-server-key.pem --ca-file ${certs}/trusted-ca-crt.pem
@ -451,7 +439,6 @@ redis host: 127.0.0.1
redis password:
redis port: 6379
</code></pre>
<p>As a new connection comes in, such output should be printed</p>
<pre><code>[2019-12-19 20:27:19.724] [info] New connection
id: 0
@ -466,7 +453,6 @@ Sec-WebSocket-Version: 13
Upgrade: websocket
User-Agent: ixwebsocket/7.5.8 macos ssl/OpenSSL OpenSSL 1.0.2q 20 Nov 2018 zlib 1.2.11
</code></pre>
<p>To connect and publish a message, do:</p>
<pre><code>$ export certs=.certs
$ cd /path/to/ws/folder
@ -483,7 +469,6 @@ $ ws cobra_publish --endpoint wss://127.0.0.1:8765 --appkey FC2F10139A2BAc53BB72
[2019-12-19 20:46:42.658] [info] Published msg 3
[2019-12-19 20:46:42.659] [info] Published message id 3 acked
</code></pre>
<p>To use OpenSSL on macOS, compile with <code>make ws_openssl</code>. First you will have to install OpenSSL libraries, which can be done with Homebrew. Use <code>make ws_mbedtls</code> accordingly to use MbedTLS.</p></div>
</div>
</div>