parent
c6be913c69
commit
b8a8ca2623
|
@ -12,7 +12,7 @@ requires "nim >= 1.2.0",
|
||||||
"chronos",
|
"chronos",
|
||||||
"httputils",
|
"httputils",
|
||||||
"chronicles",
|
"chronicles",
|
||||||
"https://github.com/status-im/news#status",
|
"https://github.com/status-im/nim-ws",
|
||||||
"chronicles",
|
"chronicles",
|
||||||
"json_serialization"
|
"json_serialization"
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
import
|
import
|
||||||
std/[strtabs, tables],
|
std/[strtabs, tables, uri, strutils],
|
||||||
chronos,
|
pkg/[chronos, ws/ws, chronicles],
|
||||||
../client
|
../client
|
||||||
|
|
||||||
export client
|
export client
|
||||||
|
|
||||||
const newsUseChronos = true
|
logScope:
|
||||||
include news
|
topics = "JSONRPC-WS-CLIENT"
|
||||||
|
|
||||||
type
|
type
|
||||||
RpcWebSocketClient* = ref object of RpcClient
|
RpcWebSocketClient* = ref object of RpcClient
|
||||||
transport*: WebSocket
|
transport*: WSSession
|
||||||
uri*: string
|
uri*: Uri
|
||||||
loop*: Future[void]
|
loop*: Future[void]
|
||||||
|
|
||||||
proc new*(T: type RpcWebSocketClient): T =
|
proc new*(T: type RpcWebSocketClient): T =
|
||||||
|
@ -30,7 +30,6 @@ method call*(self: RpcWebSocketClient, name: string,
|
||||||
if self.transport.isNil:
|
if self.transport.isNil:
|
||||||
raise newException(ValueError,
|
raise newException(ValueError,
|
||||||
"Transport is not initialised (missing a call to connect?)")
|
"Transport is not initialised (missing a call to connect?)")
|
||||||
# echo "Sent msg: ", value
|
|
||||||
|
|
||||||
# completed by processMessage.
|
# completed by processMessage.
|
||||||
var newFut = newFuture[Response]()
|
var newFut = newFuture[Response]()
|
||||||
|
@ -42,18 +41,20 @@ method call*(self: RpcWebSocketClient, name: string,
|
||||||
|
|
||||||
proc processData(client: RpcWebSocketClient) {.async.} =
|
proc processData(client: RpcWebSocketClient) {.async.} =
|
||||||
var error: ref CatchableError
|
var error: ref CatchableError
|
||||||
|
let ws = client.transport
|
||||||
try:
|
try:
|
||||||
while true:
|
while ws.readystate != ReadyState.Closed:
|
||||||
var value = await client.transport.receiveString()
|
var value = await ws.recv()
|
||||||
if value == "":
|
|
||||||
|
if value.len == 0:
|
||||||
# transmission ends
|
# transmission ends
|
||||||
break
|
break
|
||||||
|
|
||||||
client.processMessage(value)
|
client.processMessage(cast[string](value))
|
||||||
except CatchableError as e:
|
except CatchableError as e:
|
||||||
error = e
|
error = e
|
||||||
|
|
||||||
client.transport.close()
|
await client.transport.close()
|
||||||
client.transport = nil
|
client.transport = nil
|
||||||
|
|
||||||
if client.awaiting.len != 0:
|
if client.awaiting.len != 0:
|
||||||
|
@ -65,21 +66,32 @@ proc processData(client: RpcWebSocketClient) {.async.} =
|
||||||
if not client.onDisconnect.isNil:
|
if not client.onDisconnect.isNil:
|
||||||
client.onDisconnect()
|
client.onDisconnect()
|
||||||
|
|
||||||
proc connect*(client: RpcWebSocketClient, uri: string, headers: StringTableRef = nil) {.async.} =
|
proc connect*(client: RpcWebSocketClient, uri: string,
|
||||||
var headers = headers
|
flags: set[TLSFlags] = {
|
||||||
if headers.isNil:
|
NoVerifyHost, NoVerifyServerName}) {.async.} =
|
||||||
headers = newStringTable({"Origin": "http://localhost"})
|
try:
|
||||||
elif "Origin" notin headers:
|
|
||||||
# TODO: This is a hack, because the table might be case sensitive. Ideally strtabs module has
|
let uri = parseUri(uri)
|
||||||
# to be extended with case insensitive accessors.
|
let secure = uri.scheme == "wss"
|
||||||
headers["Origin"] = "http://localhost"
|
let port = parseInt(uri.port)
|
||||||
client.transport = await newWebSocket(uri, headers)
|
|
||||||
client.uri = uri
|
let ws = await WebSocket.connect(
|
||||||
|
host = uri.hostname,
|
||||||
|
port = Port(port),
|
||||||
|
path = uri.path,
|
||||||
|
secure=secure,
|
||||||
|
flags=flags
|
||||||
|
)
|
||||||
|
client.transport = ws
|
||||||
|
client.uri = uri
|
||||||
|
|
||||||
|
except WebSocketError as exc:
|
||||||
|
error "WebSocket error", exception = exc.msg
|
||||||
|
|
||||||
client.loop = processData(client)
|
client.loop = processData(client)
|
||||||
|
|
||||||
method close*(client: RpcWebSocketClient) {.async.} =
|
method close*(client: RpcWebSocketClient) {.async.} =
|
||||||
await client.loop.cancelAndWait()
|
await client.loop.cancelAndWait()
|
||||||
if not client.transport.isNil:
|
if not client.transport.isNil:
|
||||||
client.transport.close()
|
await client.transport.close()
|
||||||
client.transport = nil
|
client.transport = nil
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue