mirror of
https://github.com/simplex-chat/simplexmq.git
synced 2026-05-14 14:05:08 +00:00
docs: readme, system design
This commit is contained in:
@@ -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
|
||||
|
||||

|
||||
|
||||
@@ -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)"]
|
||||
}
|
||||
}
|
||||
@@ -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->subscriber -->
|
||||
<g id="edge13" class="edge">
|
||||
<title>msgQueues->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->runClient -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>main->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->server -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>main->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->runClient -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>ss->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->cs -->
|
||||
<g id="edge5" class="edge">
|
||||
<title>runClient->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->receive -->
|
||||
<g id="edge6" class="edge">
|
||||
<title>runClient->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->client -->
|
||||
<g id="edge7" class="edge">
|
||||
<title>runClient->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->send -->
|
||||
<g id="edge8" class="edge">
|
||||
<title>runClient->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->inq -->
|
||||
<g id="edge9" class="edge">
|
||||
<title>server->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->server -->
|
||||
<g id="edge4" class="edge">
|
||||
<title>subscribedQ->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->receive -->
|
||||
<g id="edge10" class="edge">
|
||||
<title>cs->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->inq -->
|
||||
<g id="edge11" class="edge">
|
||||
<title>receive->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->msgQueues -->
|
||||
<g id="edge17" class="edge">
|
||||
<title>client->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->queueStore -->
|
||||
<g id="edge15" class="edge">
|
||||
<title>client->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->subscribedQ -->
|
||||
<g id="edge21" class="edge">
|
||||
<title>client->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->subscriber -->
|
||||
<g id="edge16" class="edge">
|
||||
<title>client->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->outq -->
|
||||
<g id="edge18" class="edge">
|
||||
<title>client->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->cs -->
|
||||
<g id="edge20" class="edge">
|
||||
<title>send->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->client -->
|
||||
<g id="edge12" class="edge">
|
||||
<title>inq->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->outq -->
|
||||
<g id="edge14" class="edge">
|
||||
<title>subscriber->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->send -->
|
||||
<g id="edge19" class="edge">
|
||||
<title>outq->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
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user