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!"