docs: readme, system design

This commit is contained in:
Evgeny Poberezkin
2020-10-18 21:28:37 +01:00
parent 284289e4ae
commit 295b14e2e5
4 changed files with 433 additions and 4 deletions
+92
View File
@@ -1 +1,93 @@
# simplex-messaging
## SMP server demo
This is a demo implementation of SMP (simplex messaging protocol) server.
This is not usable for real applications, as it lacks the following protocol features:
- cryptographic signature verification, instead it simply compares provided "signature" with stored "public key", effectively treating them as plain text passwords.
- there is no transport encryption
These limitations make it easy to experiment with the protocol logic via telnet.
You can either run it locally or try with the deployed demo server:
```bash
telnet smp.simplex.im 5223
```
## Run locally
[Install stack](https://docs.haskellstack.org/en/stable/install_and_upgrade/) and `stack run`.
## Usage example
Lines you should send are prefixed with `>` character, you should not type them.
Comments are prefixed with `--`, they are not part of transmission.
`>` on its own means you need to press return - telnet should be configured to send CRLF.
1. Create simplex message queue:
```telnet
>
>
> CONN 1234 -- 1234 is recipient's key
IDS QuCLU4YxgS7wcPFA YB4CCATREHkaQcEh -- recipient and sender ID for the queue
```
2. Sender can send their "key" to the connection:
```telnet
> -- no signature (just press enter)
> YB4CCATREHkaQcEh -- sender ID for the queue
> SEND :key abcd
YB4CCATREHkaQcEh
OK
```
3. Secure queue with sender's "key"
```telnet
> 1234 -- "signature" - same as "key" in the demo
> QuCLU4YxgS7wcPFA -- recipient ID
> KEY abcd -- "key" provided by sender
QuCLU4YxgS7wcPFA
OK
```
4. Sender can now send messages to the queue
```telnet
> abcd
> YB4CCATREHkaQcEh
> SEND :hello
YB4CCATREHkaQcEh
OK
```
5. Recipient recieves the message and acknowledges it to receive further messages
```telnet
QuCLU4YxgS7wcPFA
MSG ECA3w3ID 2020-10-18T20:19:36.874Z 5
hello
> 1234
> QuCLU4YxgS7wcPFA
> ACK
QuCLU4YxgS7wcPFA
OK
```
## Desgin
![server design](design/server.svg)
+57
View File
@@ -0,0 +1,57 @@
digraph SMPServer {
graph [fontname=arial]
node [fontname=arial fontsize=11 shape=box]
edge [fontname=arial fontsize=10 arrowhead=open arrowtail=open]
subgraph clusterPersistence {
label="persistence (STM)"
msgQueues [shape=cylinder label="Message\nqueues\npersistence"]
queueStore [shape=cylinder label="SMP connections\n(aka SMP queues)\npersistence"]
}
subgraph clusterServer {
label="server threads"
main [shape=hexagon color=orange label="main\nthread"]
ss [label="server TCP socket" color=blue]
subgraph clusterThreads {
label=""
node [shape=hexagon color=orange]
runClient [label="runClient\nthread"]
server [label="server\nthread"]
}
subscribedQ [shape="larrow" label="subscribed\nTBQueue"]
main -> {server runClient} [style=dashed label=race color=orange fontcolor=orange]
ss -> runClient [color=blue]
subscribedQ -> server
}
subgraph clusterConnection {
label="1 group per client connection"
cs [label="client connection TCP socket" color=blue]
subgraph clusterThreads {
node [shape=hexagon, color=orange]
label=""
receive [label="receive\nthread"]
client [label="client\nthread"]
send [label="send\nthread"]
}
runClient -> cs [style=dashed label="connect" color=blue fontcolor=blue]
runClient -> {client receive send} [style=dashed label=race color=orange fontcolor=orange]
server -> inq [label="END"]
subscriber [shape=hexagon color=orange label="subscriber\nthread\n(only sends\n1 msg atm)"]
inq [shape=rarrow label="receive\nTBQueue"]
outq [shape=larrow label="send\nTBQueue"]
cs -> receive -> inq -> client [color=blue]
msgQueues -> subscriber [label="Message" color=green fontcolor=green]
subscriber -> outq [label="MSG" color=blue fontcolor=blue constraint=false]
client -> queueStore [dir=both]
client -> subscriber [style=dashed label="1 fork\nper\nqueue" color=orange]
client -> msgQueues [dir="both" label="SEND,\nSUB,\nACK" color=green]
client -> outq -> send -> cs [color=blue]
client -> subscribedQ [label="(rId,\nClient)"]
}
}
+283
View File
@@ -0,0 +1,283 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 2.40.1 (20161225.0304)
-->
<!-- Title: SMPServer Pages: 1 -->
<svg width="910pt" height="751pt"
viewBox="0.00 0.00 910.00 750.66" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 746.6609)">
<title>SMPServer</title>
<polygon fill="#ffffff" stroke="transparent" points="-4,4 -4,-746.6609 906,-746.6609 906,4 -4,4"/>
<g id="clust1" class="cluster">
<title>clusterPersistence</title>
<polygon fill="none" stroke="#000000" points="680,-155.286 680,-261.536 894,-261.536 894,-155.286 680,-155.286"/>
<text text-anchor="middle" x="787" y="-244.936" font-family="arial" font-size="14.00" fill="#000000">persistence (STM)</text>
</g>
<g id="clust2" class="cluster">
<title>clusterServer</title>
<polygon fill="none" stroke="#000000" points="8,-417.7109 8,-734.6609 314,-734.6609 314,-417.7109 8,-417.7109"/>
<text text-anchor="middle" x="161" y="-718.0609" font-family="arial" font-size="14.00" fill="#000000">server threads</text>
</g>
<g id="clust3" class="cluster">
<title>clusterThreads</title>
<polygon fill="none" stroke="#000000" points="96,-425.7109 96,-497.8859 306,-497.8859 306,-425.7109 96,-425.7109"/>
</g>
<g id="clust5" class="cluster">
<title>clusterConnection</title>
<polygon fill="none" stroke="#000000" points="322,-8 322,-618.6859 672,-618.6859 672,-8 322,-8"/>
<text text-anchor="middle" x="497" y="-602.0859" font-family="arial" font-size="14.00" fill="#000000">1 group per client connection</text>
</g>
<g id="clust6" class="cluster">
<title>clusterThreads</title>
<polygon fill="none" stroke="#000000" points="330,-315.536 330,-387.7109 621,-387.7109 621,-315.536 330,-315.536"/>
</g>
<!-- msgQueues -->
<g id="node1" class="node">
<title>msgQueues</title>
<path fill="none" stroke="#000000" d="M886.2346,-222.9713C886.2346,-226.2772 869.9937,-228.9625 850,-228.9625 830.0063,-228.9625 813.7654,-226.2772 813.7654,-222.9713 813.7654,-222.9713 813.7654,-169.0506 813.7654,-169.0506 813.7654,-165.7448 830.0063,-163.0594 850,-163.0594 869.9937,-163.0594 886.2346,-165.7448 886.2346,-169.0506 886.2346,-169.0506 886.2346,-222.9713 886.2346,-222.9713"/>
<path fill="none" stroke="#000000" d="M886.2346,-222.9713C886.2346,-219.6655 869.9937,-216.9802 850,-216.9802 830.0063,-216.9802 813.7654,-219.6655 813.7654,-222.9713"/>
<text text-anchor="middle" x="850" y="-205.911" font-family="arial" font-size="11.00" fill="#000000">Message</text>
<text text-anchor="middle" x="850" y="-192.711" font-family="arial" font-size="11.00" fill="#000000">queues</text>
<text text-anchor="middle" x="850" y="-179.511" font-family="arial" font-size="11.00" fill="#000000">persistence</text>
</g>
<!-- subscriber -->
<g id="node13" class="node">
<title>subscriber</title>
<polygon fill="none" stroke="#ffa500" points="663.958,-65.643 634.479,-115.4294 575.521,-115.4294 546.042,-65.643 575.521,-15.8566 634.479,-15.8566 663.958,-65.643"/>
<text text-anchor="middle" x="605" y="-82.143" font-family="arial" font-size="11.00" fill="#000000">subscriber</text>
<text text-anchor="middle" x="605" y="-68.943" font-family="arial" font-size="11.00" fill="#000000">thread</text>
<text text-anchor="middle" x="605" y="-55.743" font-family="arial" font-size="11.00" fill="#000000">(only sends</text>
<text text-anchor="middle" x="605" y="-42.543" font-family="arial" font-size="11.00" fill="#000000">1 msg atm)</text>
</g>
<!-- msgQueues&#45;&gt;subscriber -->
<g id="edge13" class="edge">
<title>msgQueues&#45;&gt;subscriber</title>
<path fill="none" stroke="#00ff00" d="M818.0484,-164.9352C813.816,-161.4753 809.4112,-158.1665 805,-155.286 760.3684,-126.1423 704.6937,-102.0511 663.4267,-86.2098"/>
<polygon fill="#00ff00" stroke="#00ff00" points="654.0575,-82.6597 665.0033,-81.9951 658.7331,-84.4314 663.4087,-86.2031 663.4087,-86.2031 663.4087,-86.2031 658.7331,-84.4314 661.8142,-90.4111 654.0575,-82.6597 654.0575,-82.6597"/>
<text text-anchor="middle" x="804.2825" y="-136.286" font-family="arial" font-size="10.00" fill="#00ff00">Message</text>
</g>
<!-- queueStore -->
<g id="node2" class="node">
<title>queueStore</title>
<path fill="none" stroke="#000000" d="M795.5756,-222.9713C795.5756,-226.2772 771.5622,-228.9625 742,-228.9625 712.4378,-228.9625 688.4244,-226.2772 688.4244,-222.9713 688.4244,-222.9713 688.4244,-169.0506 688.4244,-169.0506 688.4244,-165.7448 712.4378,-163.0594 742,-163.0594 771.5622,-163.0594 795.5756,-165.7448 795.5756,-169.0506 795.5756,-169.0506 795.5756,-222.9713 795.5756,-222.9713"/>
<path fill="none" stroke="#000000" d="M795.5756,-222.9713C795.5756,-219.6655 771.5622,-216.9802 742,-216.9802 712.4378,-216.9802 688.4244,-219.6655 688.4244,-222.9713"/>
<text text-anchor="middle" x="742" y="-205.911" font-family="arial" font-size="11.00" fill="#000000">SMP connections</text>
<text text-anchor="middle" x="742" y="-192.711" font-family="arial" font-size="11.00" fill="#000000">(aka SMP queues)</text>
<text text-anchor="middle" x="742" y="-179.511" font-family="arial" font-size="11.00" fill="#000000">persistence</text>
</g>
<!-- main -->
<g id="node3" class="node">
<title>main</title>
<polygon fill="none" stroke="#ffa500" points="93.542,-673.7734 74.271,-701.9486 35.729,-701.9486 16.458,-673.7734 35.729,-645.5982 74.271,-645.5982 93.542,-673.7734"/>
<text text-anchor="middle" x="55" y="-677.0734" font-family="arial" font-size="11.00" fill="#000000">main</text>
<text text-anchor="middle" x="55" y="-663.8734" font-family="arial" font-size="11.00" fill="#000000">thread</text>
</g>
<!-- runClient -->
<g id="node5" class="node">
<title>runClient</title>
<polygon fill="none" stroke="#ffa500" points="297.9814,-461.7984 273.4907,-489.9737 224.5093,-489.9737 200.0186,-461.7984 224.5093,-433.6232 273.4907,-433.6232 297.9814,-461.7984"/>
<text text-anchor="middle" x="249" y="-465.0984" font-family="arial" font-size="11.00" fill="#000000">runClient</text>
<text text-anchor="middle" x="249" y="-451.8984" font-family="arial" font-size="11.00" fill="#000000">thread</text>
</g>
<!-- main&#45;&gt;runClient -->
<g id="edge1" class="edge">
<title>main&#45;&gt;runClient</title>
<path fill="none" stroke="#ffa500" stroke-dasharray="5,2" d="M82.1578,-656.6335C97.1002,-646.5366 115.4954,-632.9686 130,-618.6859 167.6779,-581.5844 203.2683,-532.0423 225.5388,-498.6376"/>
<polygon fill="#ffa500" stroke="#ffa500" points="231.1821,-490.0893 229.4281,-500.914 228.4274,-494.2621 225.6727,-498.4348 225.6727,-498.4348 225.6727,-498.4348 228.4274,-494.2621 221.9172,-495.9556 231.1821,-490.0893 231.1821,-490.0893"/>
<text text-anchor="middle" x="198.7235" y="-564.8859" font-family="arial" font-size="10.00" fill="#ffa500">race</text>
</g>
<!-- server -->
<g id="node6" class="node">
<title>server</title>
<polygon fill="none" stroke="#ffa500" points="181.542,-461.7984 162.271,-489.9737 123.729,-489.9737 104.458,-461.7984 123.729,-433.6232 162.271,-433.6232 181.542,-461.7984"/>
<text text-anchor="middle" x="143" y="-465.0984" font-family="arial" font-size="11.00" fill="#000000">server</text>
<text text-anchor="middle" x="143" y="-451.8984" font-family="arial" font-size="11.00" fill="#000000">thread</text>
</g>
<!-- main&#45;&gt;server -->
<g id="edge2" class="edge">
<title>main&#45;&gt;server</title>
<path fill="none" stroke="#ffa500" stroke-dasharray="5,2" d="M66.6857,-645.6248C82.3006,-608.0115 110.0166,-541.2491 127.4019,-499.3712"/>
<polygon fill="#ffa500" stroke="#ffa500" points="131.2659,-490.0635 131.5878,-501.0247 129.3488,-494.6814 127.4317,-499.2993 127.4317,-499.2993 127.4317,-499.2993 129.3488,-494.6814 123.2756,-497.5739 131.2659,-490.0635 131.2659,-490.0635"/>
<text text-anchor="middle" x="116.7235" y="-564.8859" font-family="arial" font-size="10.00" fill="#ffa500">race</text>
</g>
<!-- ss -->
<g id="node4" class="node">
<title>ss</title>
<polygon fill="none" stroke="#0000ff" points="218.4518,-691.7734 111.5482,-691.7734 111.5482,-655.7734 218.4518,-655.7734 218.4518,-691.7734"/>
<text text-anchor="middle" x="165" y="-670.4734" font-family="arial" font-size="11.00" fill="#000000">server TCP socket</text>
</g>
<!-- ss&#45;&gt;runClient -->
<g id="edge3" class="edge">
<title>ss&#45;&gt;runClient</title>
<path fill="none" stroke="#0000ff" d="M190.6974,-655.6287C202.3984,-645.9977 215.3212,-633.1626 223,-618.6859 242.6119,-581.7119 248.114,-533.5135 249.3398,-500.3492"/>
<polygon fill="#0000ff" stroke="#0000ff" points="249.6001,-490.1431 253.8436,-500.2546 249.4726,-495.1415 249.3451,-500.1399 249.3451,-500.1399 249.3451,-500.1399 249.4726,-495.1415 244.8465,-500.0251 249.6001,-490.1431 249.6001,-490.1431"/>
</g>
<!-- cs -->
<g id="node8" class="node">
<title>cs</title>
<polygon fill="none" stroke="#0000ff" points="552.8099,-585.8859 395.1901,-585.8859 395.1901,-549.8859 552.8099,-549.8859 552.8099,-585.8859"/>
<text text-anchor="middle" x="474" y="-564.5859" font-family="arial" font-size="11.00" fill="#000000">client connection TCP socket</text>
</g>
<!-- runClient&#45;&gt;cs -->
<g id="edge5" class="edge">
<title>runClient&#45;&gt;cs</title>
<path fill="none" stroke="#0000ff" stroke-dasharray="5,2" d="M266.9422,-489.9934C277.6982,-504.6484 292.6446,-521.5997 309.985,-531.8859 323.277,-539.7706 353.6924,-547.2993 384.7675,-553.4144"/>
<polygon fill="#0000ff" stroke="#0000ff" points="394.8591,-555.3488 384.1907,-557.8857 389.9485,-554.4075 385.0379,-553.4662 385.0379,-553.4662 385.0379,-553.4662 389.9485,-554.4075 385.8851,-549.0467 394.8591,-555.3488 394.8591,-555.3488"/>
<text text-anchor="middle" x="326.5075" y="-516.8859" font-family="arial" font-size="10.00" fill="#0000ff">connect</text>
</g>
<!-- receive -->
<g id="node9" class="node">
<title>receive</title>
<polygon fill="none" stroke="#ffa500" points="422.0134,-351.6235 401.0067,-379.7987 358.9933,-379.7987 337.9866,-351.6235 358.9933,-323.4482 401.0067,-323.4482 422.0134,-351.6235"/>
<text text-anchor="middle" x="380" y="-354.9235" font-family="arial" font-size="11.00" fill="#000000">receive</text>
<text text-anchor="middle" x="380" y="-341.7235" font-family="arial" font-size="11.00" fill="#000000">thread</text>
</g>
<!-- runClient&#45;&gt;receive -->
<g id="edge6" class="edge">
<title>runClient&#45;&gt;receive</title>
<path fill="none" stroke="#ffa500" stroke-dasharray="5,2" d="M242.4559,-433.4059C241.3023,-421.3888 242.3132,-407.8541 249.553,-397.7109 259.7013,-383.493 300.429,-370.5535 333.711,-362.0296"/>
<polygon fill="#ffa500" stroke="#ffa500" points="343.7588,-359.5295 335.1413,-366.311 338.9067,-360.7368 334.0547,-361.9441 334.0547,-361.9441 334.0547,-361.9441 338.9067,-360.7368 332.9681,-357.5773 343.7588,-359.5295 343.7588,-359.5295"/>
<text text-anchor="middle" x="258.7235" y="-400.7109" font-family="arial" font-size="10.00" fill="#ffa500">race</text>
</g>
<!-- client -->
<g id="node10" class="node">
<title>client</title>
<polygon fill="none" stroke="#ffa500" points="612.542,-351.6235 593.271,-379.7987 554.729,-379.7987 535.458,-351.6235 554.729,-323.4482 593.271,-323.4482 612.542,-351.6235"/>
<text text-anchor="middle" x="574" y="-354.9235" font-family="arial" font-size="11.00" fill="#000000">client</text>
<text text-anchor="middle" x="574" y="-341.7235" font-family="arial" font-size="11.00" fill="#000000">thread</text>
</g>
<!-- runClient&#45;&gt;client -->
<g id="edge7" class="edge">
<title>runClient&#45;&gt;client</title>
<path fill="none" stroke="#ffa500" stroke-dasharray="5,2" d="M277.06,-437.6595C296.597,-421.4244 321.2685,-402.1967 333.553,-397.7109 414.4215,-368.1815 446.2239,-417.4923 527,-387.7109 532.1882,-385.7981 537.2696,-383.0977 542.0605,-380.0246"/>
<polygon fill="#ffa500" stroke="#ffa500" points="550.3305,-374.1805 544.7608,-383.6267 546.2472,-377.0661 542.1638,-379.9517 542.1638,-379.9517 542.1638,-379.9517 546.2472,-377.0661 539.5668,-376.2767 550.3305,-374.1805 550.3305,-374.1805"/>
<text text-anchor="middle" x="342.7235" y="-400.7109" font-family="arial" font-size="10.00" fill="#ffa500">race</text>
</g>
<!-- send -->
<g id="node11" class="node">
<title>send</title>
<polygon fill="none" stroke="#ffa500" points="517.542,-351.6235 498.271,-379.7987 459.729,-379.7987 440.458,-351.6235 459.729,-323.4482 498.271,-323.4482 517.542,-351.6235"/>
<text text-anchor="middle" x="479" y="-354.9235" font-family="arial" font-size="11.00" fill="#000000">send</text>
<text text-anchor="middle" x="479" y="-341.7235" font-family="arial" font-size="11.00" fill="#000000">thread</text>
</g>
<!-- runClient&#45;&gt;send -->
<g id="edge8" class="edge">
<title>runClient&#45;&gt;send</title>
<path fill="none" stroke="#ffa500" stroke-dasharray="5,2" d="M260.5478,-433.5923C267.4946,-420.3735 277.7098,-405.787 291.553,-397.7109 318.388,-382.0555 401.9033,-398.6009 431,-387.7109 436.5046,-385.6507 441.9126,-382.7479 446.9995,-379.4734"/>
<polygon fill="#ffa500" stroke="#ffa500" points="455.2178,-373.6949 449.6258,-383.1279 451.1276,-376.5708 447.0375,-379.4467 447.0375,-379.4467 447.0375,-379.4467 451.1276,-376.5708 444.4492,-375.7656 455.2178,-373.6949 455.2178,-373.6949"/>
<text text-anchor="middle" x="300.7235" y="-400.7109" font-family="arial" font-size="10.00" fill="#ffa500">race</text>
</g>
<!-- inq -->
<g id="node12" class="node">
<title>inq</title>
<polygon fill="none" stroke="#000000" points="375.5723,-77.643 330.4277,-77.643 330.4277,-53.643 375.5723,-53.643 375.5723,-47.643 393.5723,-65.643 375.5723,-83.643 375.5723,-77.643"/>
<text text-anchor="middle" x="362" y="-68.943" font-family="arial" font-size="11.00" fill="#000000">receive</text>
<text text-anchor="middle" x="362" y="-55.743" font-family="arial" font-size="11.00" fill="#000000">TBQueue</text>
</g>
<!-- server&#45;&gt;inq -->
<g id="edge9" class="edge">
<title>server&#45;&gt;inq</title>
<path fill="none" stroke="#000000" d="M158.5744,-433.6255C199.0689,-360.3738 307.2719,-164.6422 347.055,-92.6775"/>
<polygon fill="#000000" stroke="#000000" points="351.9874,-83.755 351.0876,-94.6839 349.5684,-88.1309 347.1493,-92.5068 347.1493,-92.5068 347.1493,-92.5068 349.5684,-88.1309 343.211,-90.3296 351.9874,-83.755 351.9874,-83.755"/>
<text text-anchor="middle" x="257.5535" y="-284.536" font-family="arial" font-size="10.00" fill="#000000">END</text>
</g>
<!-- subscribedQ -->
<g id="node7" class="node">
<title>subscribedQ</title>
<polygon fill="none" stroke="#000000" points="305.6775,-685.7734 254.3225,-685.7734 254.3225,-691.7734 236.3225,-673.7734 254.3225,-655.7734 254.3225,-661.7734 305.6775,-661.7734 305.6775,-685.7734"/>
<text text-anchor="middle" x="271" y="-677.0734" font-family="arial" font-size="11.00" fill="#000000">subscribed</text>
<text text-anchor="middle" x="271" y="-663.8734" font-family="arial" font-size="11.00" fill="#000000">TBQueue</text>
</g>
<!-- subscribedQ&#45;&gt;server -->
<g id="edge4" class="edge">
<title>subscribedQ&#45;&gt;server</title>
<path fill="none" stroke="#000000" d="M266.2392,-655.5839C259.1914,-630.5454 244.4608,-584.6176 223,-549.8859 209.5338,-528.0925 190.3419,-506.7431 174.1312,-490.5215"/>
<polygon fill="#000000" stroke="#000000" points="166.9242,-483.4459 177.2126,-487.2405 170.4921,-486.9488 174.0601,-490.4516 174.0601,-490.4516 174.0601,-490.4516 170.4921,-486.9488 170.9075,-493.6628 166.9242,-483.4459 166.9242,-483.4459"/>
</g>
<!-- cs&#45;&gt;receive -->
<g id="edge10" class="edge">
<title>cs&#45;&gt;receive</title>
<path fill="none" stroke="#0000ff" d="M466.1473,-549.8195C450.8321,-514.5843 416.6919,-436.0391 396.288,-389.0967"/>
<polygon fill="#0000ff" stroke="#0000ff" points="392.2772,-379.8691 400.3905,-387.2464 394.2703,-384.4547 396.2635,-389.0403 396.2635,-389.0403 396.2635,-389.0403 394.2703,-384.4547 392.1365,-390.8341 392.2772,-379.8691 392.2772,-379.8691"/>
</g>
<!-- receive&#45;&gt;inq -->
<g id="edge11" class="edge">
<title>receive&#45;&gt;inq</title>
<path fill="none" stroke="#0000ff" d="M378.2248,-323.4199C374.7824,-268.7272 367.2355,-148.8234 363.7851,-94.005"/>
<polygon fill="#0000ff" stroke="#0000ff" points="363.1521,-83.9478 368.2715,-93.6453 363.4663,-88.9379 363.7804,-93.928 363.7804,-93.928 363.7804,-93.928 363.4663,-88.9379 359.2893,-94.2107 363.1521,-83.9478 363.1521,-83.9478"/>
</g>
<!-- client&#45;&gt;msgQueues -->
<g id="edge17" class="edge">
<title>client&#45;&gt;msgQueues</title>
<path fill="none" stroke="#00ff00" d="M617.9267,-342.7233C667.5371,-330.9275 748.6743,-306.1996 805,-261.536 813.4402,-254.8433 820.917,-246.1403 827.2332,-237.2751"/>
<polygon fill="#00ff00" stroke="#00ff00" points="608.1406,-344.9794 616.874,-338.3479 613.0128,-343.8561 617.885,-342.7328 617.885,-342.7328 617.885,-342.7328 613.0128,-343.8561 618.8959,-347.1178 608.1406,-344.9794 608.1406,-344.9794"/>
<polygon fill="#00ff00" stroke="#00ff00" points="832.9269,-228.7861 831.0938,-239.5977 830.1417,-232.9386 827.3566,-237.0911 827.3566,-237.0911 827.3566,-237.0911 830.1417,-232.9386 823.6193,-234.5844 832.9269,-228.7861 832.9269,-228.7861"/>
<text text-anchor="middle" x="803.2775" y="-296.536" font-family="arial" font-size="10.00" fill="#000000">SEND,</text>
<text text-anchor="middle" x="803.2775" y="-284.536" font-family="arial" font-size="10.00" fill="#000000">SUB,</text>
<text text-anchor="middle" x="803.2775" y="-272.536" font-family="arial" font-size="10.00" fill="#000000">ACK</text>
</g>
<!-- client&#45;&gt;queueStore -->
<g id="edge15" class="edge">
<title>client&#45;&gt;queueStore</title>
<path fill="none" stroke="#000000" d="M612.5056,-333.6124C626.6519,-326.0237 642.3006,-316.4164 655,-305.536 678.0563,-285.7822 699.3432,-259.1992 715.0896,-237.1694"/>
<polygon fill="#000000" stroke="#000000" points="603.4726,-338.3008 610.2752,-329.6999 607.9104,-335.9974 612.3483,-333.694 612.3483,-333.694 612.3483,-333.694 607.9104,-335.9974 614.4213,-337.6881 603.4726,-338.3008 603.4726,-338.3008"/>
<polygon fill="#000000" stroke="#000000" points="720.8455,-228.9729 718.7812,-239.7427 717.972,-233.0647 715.0985,-237.1566 715.0985,-237.1566 715.0985,-237.1566 717.972,-233.0647 711.4159,-234.5705 720.8455,-228.9729 720.8455,-228.9729"/>
</g>
<!-- client&#45;&gt;subscribedQ -->
<g id="edge21" class="edge">
<title>client&#45;&gt;subscribedQ</title>
<path fill="none" stroke="#000000" d="M548.853,-371.3985C541.8457,-376.7806 534.1842,-382.5475 527,-387.7109 449.2252,-443.6094 398.5216,-426.4431 348.117,-507.8859 342.4564,-517.0322 348.2294,-521.6259 345,-531.8859 331.6605,-574.2659 306.1092,-619.0674 288.8091,-646.7266"/>
<polygon fill="#000000" stroke="#000000" points="283.2879,-655.4212 284.8498,-644.5671 285.9683,-651.2003 288.6486,-646.9794 288.6486,-646.9794 288.6486,-646.9794 285.9683,-651.2003 292.4474,-649.3916 283.2879,-655.4212 283.2879,-655.4212"/>
<text text-anchor="middle" x="362.4415" y="-522.8859" font-family="arial" font-size="10.00" fill="#000000">(rId,</text>
<text text-anchor="middle" x="362.4415" y="-510.8859" font-family="arial" font-size="10.00" fill="#000000">Client)</text>
</g>
<!-- client&#45;&gt;subscriber -->
<g id="edge16" class="edge">
<title>client&#45;&gt;subscriber</title>
<path fill="none" stroke="#ffa500" stroke-dasharray="5,2" d="M577.0572,-323.4199C582.0173,-277.6627 591.9251,-186.2615 598.5098,-125.5165"/>
<polygon fill="#ffa500" stroke="#ffa500" points="599.6176,-115.2965 603.0136,-125.7233 599.0787,-120.2674 598.5398,-125.2383 598.5398,-125.2383 598.5398,-125.2383 599.0787,-120.2674 594.0661,-124.7533 599.6176,-115.2965 599.6176,-115.2965"/>
<text text-anchor="middle" x="608.8975" y="-205.011" font-family="arial" font-size="10.00" fill="#000000">1 fork</text>
<text text-anchor="middle" x="608.8975" y="-193.011" font-family="arial" font-size="10.00" fill="#000000">per</text>
<text text-anchor="middle" x="608.8975" y="-181.011" font-family="arial" font-size="10.00" fill="#000000">queue</text>
</g>
<!-- outq -->
<g id="node14" class="node">
<title>outq</title>
<polygon fill="none" stroke="#000000" points="474.5723,-77.643 429.4277,-77.643 429.4277,-83.643 411.4277,-65.643 429.4277,-47.643 429.4277,-53.643 474.5723,-53.643 474.5723,-77.643"/>
<text text-anchor="middle" x="443" y="-68.943" font-family="arial" font-size="11.00" fill="#000000">send</text>
<text text-anchor="middle" x="443" y="-55.743" font-family="arial" font-size="11.00" fill="#000000">TBQueue</text>
</g>
<!-- client&#45;&gt;outq -->
<g id="edge18" class="edge">
<title>client&#45;&gt;outq</title>
<path fill="none" stroke="#0000ff" d="M568.6677,-323.2208C559.7246,-280.037 539.0456,-196.2417 503,-133.286 494.2343,-117.9763 481.6018,-103.0724 470.1868,-91.1685"/>
<polygon fill="#0000ff" stroke="#0000ff" points="462.9142,-83.805 473.143,-87.7577 466.4278,-87.3624 469.9413,-90.9199 469.9413,-90.9199 469.9413,-90.9199 466.4278,-87.3624 466.7396,-94.082 462.9142,-83.805 462.9142,-83.805"/>
</g>
<!-- send&#45;&gt;cs -->
<g id="edge20" class="edge">
<title>send&#45;&gt;cs</title>
<path fill="none" stroke="#0000ff" d="M478.347,-379.8691C477.3889,-421.308 475.6125,-498.1421 474.6539,-539.6025"/>
<polygon fill="#0000ff" stroke="#0000ff" points="474.4177,-549.8195 470.1501,-539.7181 474.5333,-544.8208 474.6489,-539.8221 474.6489,-539.8221 474.6489,-539.8221 474.5333,-544.8208 479.1477,-539.9262 474.4177,-549.8195 474.4177,-549.8195"/>
</g>
<!-- inq&#45;&gt;client -->
<g id="edge12" class="edge">
<title>inq&#45;&gt;client</title>
<path fill="none" stroke="#0000ff" d="M375.4315,-83.7616C409.9367,-130.3079 502.1675,-254.724 547.7526,-316.2167"/>
<polygon fill="#0000ff" stroke="#0000ff" points="553.8644,-324.4613 544.2941,-319.1078 550.8868,-320.4446 547.9092,-316.4279 547.9092,-316.4279 547.9092,-316.4279 550.8868,-320.4446 551.5242,-313.748 553.8644,-324.4613 553.8644,-324.4613"/>
</g>
<!-- subscriber&#45;&gt;outq -->
<g id="edge14" class="edge">
<title>subscriber&#45;&gt;outq</title>
<path fill="none" stroke="#0000ff" d="M545.9162,-65.643C525.661,-65.643 503.4286,-65.643 484.8268,-65.643"/>
<polygon fill="#0000ff" stroke="#0000ff" points="474.6198,-65.643 484.6198,-61.1431 479.6198,-65.643 484.6198,-65.6431 484.6198,-65.6431 484.6198,-65.6431 479.6198,-65.643 484.6198,-70.1431 474.6198,-65.643 474.6198,-65.643"/>
<text text-anchor="middle" x="510.2786" y="-71.643" font-family="arial" font-size="10.00" fill="#0000ff">MSG</text>
</g>
<!-- outq&#45;&gt;send -->
<g id="edge19" class="edge">
<title>outq&#45;&gt;send</title>
<path fill="none" stroke="#0000ff" d="M445.3043,-83.9478C451.0874,-129.8886 466.3126,-250.8361 474.1643,-313.2088"/>
<polygon fill="#0000ff" stroke="#0000ff" points="475.4497,-323.4199 469.7358,-314.0603 474.8251,-318.459 474.2006,-313.4982 474.2006,-313.4982 474.2006,-313.4982 474.8251,-318.459 478.6654,-312.9361 475.4497,-323.4199 475.4497,-323.4199"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 22 KiB

+1 -4
View File
@@ -62,14 +62,11 @@ startTCPClient host port = liftIO . withSocketsDo $ resolve >>= open
runTCPClient :: MonadUnliftIO m => HostName -> ServiceName -> (Handle -> m a) -> m a
runTCPClient host port = E.bracket (startTCPClient host port) IO.hClose
smpNewlineMode :: NewlineMode
smpNewlineMode = NewlineMode {inputNL = CRLF, outputNL = CRLF}
getSocketHandle :: MonadIO m => Socket -> m Handle
getSocketHandle conn = liftIO $ do
h <- socketToHandle conn ReadWriteMode
hSetBinaryMode h True
hSetNewlineMode h smpNewlineMode
hSetNewlineMode h NewlineMode {inputNL = CRLF, outputNL = CRLF}
hSetBuffering h LineBuffering
return h