I've attempted several approaches with this including trying to mix threads and async.
what would be the best way to say send connect three sockets and read from each of the asynchronously?
https://github.com/treeform/ws/blob/master/tests/sender_3.nim
import ws, asyncdispatch, asynchttpserver, httpclient
# Create three sockets and read from each of them asynchronously
var numOpenWs = 0
proc doStuff(ws: WebSocket, idx: int, msg: string) {.async.} =
inc numOpenWs
await ws.send(msg)
echo idx, ": ", await ws.receiveStrPacket()
ws.close()
dec numOpenWs
proc main() {.async.} =
var
ws1 = await newWebSocket("wss://echo.websocket.org")
ws2 = await newWebSocket("wss://echo.websocket.org")
ws3 = await newWebSocket("wss://echo.websocket.org")
echo "all sockets opened"
asyncCheck ws1.doStuff(1, "you are first")
asyncCheck ws2.doStuff(2, "you are second")
asyncCheck ws3.doStuff(3, "you are third")
echo "now just waiting for all sockets to close"
while numOpenWs > 0:
await sleepAsync(10)
waitFor main()
send connect three sockets and read from each of the asynchronously?
like this?
import asyncnet, asyncdispatch, strutils, random
proc genAddr(): string =
randomize()
var
ip0 = rand(1..255)
ip1 = rand(255)
ip2 = rand(255)
ip3 = rand(255)
(join([$ip0, $ip1, $ip2, $ip3], "."))
proc main() {.async.} =
var
sock0 = newAsyncSocket()
sock1 = newAsyncSocket()
sock2 = newAsyncSocket()
res0: string
res1: string
res2: string
host0 = genAddr()
host1 = genAddr()
host2 = genAddr()
await sock0.connect(host0, Port 22)
await sock1.connect(host1, Port 22)
await sock2.connect(host2, Port 22)
let
read0 = sock0.recvLine()
read1 = sock1.recvLine()
read2 = sock2.recvLine()
#[
var
read0Complete = false
read1Complete = false
read2Complete = false
while true:
if read0Complete and read1Complete and read2Complete:
break
if read0.finished and not read0.failed and not read0Complete:
read0Complete = true
res0 = read read0
elif read1.finished and not read1.failed and not read1Complete:
read1Complete = true
res1 = read read1
elif read2.finished and not read2.failed and not read2Complete:
read2Complete = true
res2 = read read0
echo res0
echo res1
echo res2
]#
# easier, if we just need to wait all results
for line in await all(read0, read1, read2):
echo line
waitFor main()
Issue I'm seeming to have is timeout never occurs upon false connections
Try to wrap with connection future withTimeout like
let
conn1 = sock0.connect(host, Port 22).withTimeout(1000)
conn2 = sock1.connect(host, Port 22).withTimeout(1000)
conn3 = sock2.connect(host, Port 22).withTimeout(1000)
if not await(conn1) or not await(conn2) or not await(conn3):
echo "timeout reached in any connection"
#untested
I did timeout this way:
let connectedSocket = socket.connect(serverAddress, port.Port) # : Future[void]
waitFor connectedSocket or sleepAsync(10000)
if not connectedSocket.finished :
quit("Timeout. Could not reach the server. Quitting...")
echo "Connected!"