2020-08-22 00:50:38 +02:00
|
|
|
module websocket
|
|
|
|
|
2020-11-15 21:54:47 +01:00
|
|
|
import net
|
2020-08-22 00:50:38 +02:00
|
|
|
import time
|
2020-12-02 04:02:53 +01:00
|
|
|
import sync
|
2020-08-22 00:50:38 +02:00
|
|
|
|
2020-11-15 21:54:47 +01:00
|
|
|
// socket_read reads into the provided buffer with its length
|
|
|
|
fn (mut ws Client) socket_read(mut buffer []byte) ?int {
|
2020-08-22 00:50:38 +02:00
|
|
|
lock {
|
2020-11-21 14:45:45 +01:00
|
|
|
if ws.state in [.closed, .closing] || ws.conn.sock.handle <= 1 {
|
|
|
|
return error('socket_read: trying to read a closed socket')
|
|
|
|
}
|
2020-08-22 00:50:38 +02:00
|
|
|
if ws.is_ssl {
|
2020-12-02 04:02:53 +01:00
|
|
|
r := ws.ssl_conn.read_into(mut buffer) ?
|
2020-08-22 00:50:38 +02:00
|
|
|
return r
|
|
|
|
} else {
|
|
|
|
for {
|
2020-11-15 21:54:47 +01:00
|
|
|
r := ws.conn.read(mut buffer) or {
|
2020-08-22 00:50:38 +02:00
|
|
|
if errcode == net.err_timed_out_code {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
return error(err)
|
|
|
|
}
|
|
|
|
return r
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-02 04:02:53 +01:00
|
|
|
// socket_read reads into the provided byte pointer and length
|
2020-11-15 21:54:47 +01:00
|
|
|
fn (mut ws Client) socket_read_ptr(buf_ptr byteptr, len int) ?int {
|
2020-08-22 00:50:38 +02:00
|
|
|
lock {
|
2020-11-21 14:45:45 +01:00
|
|
|
if ws.state in [.closed, .closing] || ws.conn.sock.handle <= 1 {
|
|
|
|
return error('socket_read_ptr: trying to read a closed socket')
|
2020-12-02 04:02:53 +01:00
|
|
|
}
|
2020-08-22 00:50:38 +02:00
|
|
|
if ws.is_ssl {
|
2020-12-02 04:02:53 +01:00
|
|
|
r := ws.ssl_conn.socket_read_into_ptr(buf_ptr, len) ?
|
2020-08-22 00:50:38 +02:00
|
|
|
return r
|
|
|
|
} else {
|
|
|
|
for {
|
2020-11-15 21:54:47 +01:00
|
|
|
r := ws.conn.read_ptr(buf_ptr, len) or {
|
2020-08-22 00:50:38 +02:00
|
|
|
if errcode == net.err_timed_out_code {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
return error(err)
|
|
|
|
}
|
|
|
|
return r
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// socket_write, writes the whole byte array provided to the socket
|
|
|
|
fn (mut ws Client) socket_write(bytes []byte) ? {
|
|
|
|
lock {
|
|
|
|
if ws.state == .closed || ws.conn.sock.handle <= 1 {
|
2020-11-21 14:45:45 +01:00
|
|
|
ws.debug_log('socket_write: Socket allready closed')
|
|
|
|
return error('socket_write: trying to write on a closed socket')
|
2020-08-22 00:50:38 +02:00
|
|
|
}
|
|
|
|
if ws.is_ssl {
|
2020-12-02 04:02:53 +01:00
|
|
|
ws.ssl_conn.write(bytes) ?
|
2020-08-22 00:50:38 +02:00
|
|
|
} else {
|
|
|
|
for {
|
|
|
|
ws.conn.write(bytes) or {
|
|
|
|
if errcode == net.err_timed_out_code {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
return error(err)
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-02 04:02:53 +01:00
|
|
|
// shutdown_socket, shut down socket properly closing the connection
|
2020-08-22 00:50:38 +02:00
|
|
|
fn (mut ws Client) shutdown_socket() ? {
|
|
|
|
ws.debug_log('shutting down socket')
|
|
|
|
if ws.is_ssl {
|
2020-12-02 04:02:53 +01:00
|
|
|
ws.ssl_conn.shutdown() ?
|
2020-08-22 00:50:38 +02:00
|
|
|
} else {
|
2020-12-02 04:02:53 +01:00
|
|
|
ws.conn.close() ?
|
2020-08-22 00:50:38 +02:00
|
|
|
}
|
|
|
|
return none
|
|
|
|
}
|
|
|
|
|
|
|
|
// dial_socket, setup socket communication, options and timeouts
|
|
|
|
fn (mut ws Client) dial_socket() ?net.TcpConn {
|
2020-12-02 04:02:53 +01:00
|
|
|
mut t := net.dial_tcp('$ws.uri.hostname:$ws.uri.port') ?
|
2020-08-22 00:50:38 +02:00
|
|
|
optval := int(1)
|
2020-12-02 04:02:53 +01:00
|
|
|
t.sock.set_option_int(.keep_alive, optval) ?
|
2020-08-22 00:50:38 +02:00
|
|
|
t.set_read_timeout(10 * time.millisecond)
|
|
|
|
t.set_write_timeout(10 * time.millisecond)
|
|
|
|
if ws.is_ssl {
|
2020-12-02 04:02:53 +01:00
|
|
|
ws.ssl_conn.connect(mut t) ?
|
2020-08-22 00:50:38 +02:00
|
|
|
}
|
|
|
|
return t
|
|
|
|
}
|