//udp socket对象
struct UdpSocket {
Socket
l Addr
// TODO(emily): replace with option again
// when i figure out how to coerce it properly
mut:
has_r bool
r Addr
}
//返回客户端对象
pub struct Client {
is_server bool
mut:
ssl_conn &openssl.SSLConn // secure connection used when wss is used
flags []Flag // flags used in handshake
fragments []Fragment // current fragments
message_callbacks []MessageEventHandler // all callbacks on_message
error_callbacks []ErrorEventHandler // all callbacks on_error
open_callbacks []OpenEventHandler // all callbacks on_open
close_callbacks []CloseEventHandler // all callbacks on_close
pub:
is_ssl bool // true if secure socket is used
uri Uri // uri of current connection
id string // unique id of client
pub mut:
header http.Header // headers that will be passed when connecting
conn &net.TcpConn // underlying TCP socket connection
nonce_size int = 16 // size of nounce used for masking
panic_on_callback bool // set to true of callbacks can panic
state State // current state of connection
logger &log.Log // logger used to log messages
resource_name string // name of current resource
last_pong_ut i64 // last time in unix time we got a pong message
}
//创建websocket服务端
pub fn new_server(family net.AddrFamily, port int, route string) &Server
//返回服务端对象
pub struct Server {
mut:
logger &log.Log // logger used to log
ls &net.TcpListener // listener used to get incoming connection to socket
accept_client_callbacks []AcceptClientFn // accept client callback functions
message_callbacks []MessageEventHandler // new message callback functions
close_callbacks []CloseEventHandler // close message callback functions
pub:
family net.AddrFamily = .ip
port int // port used as listen to incoming connections
is_ssl bool // true if secure connection (not supported yet on server)
pub mut:
clients map[string]&ServerClient // clients connected to this server
ping_interval int = 30 // interval for sending ping to clients (seconds)
state State // current state of connection
}
struct ServerClient {
pub:
resource_name string // resource that the client access
client_key string // unique key of client
pub mut:
server &Server
client &Client
}
module main
import net.websocket
import time
fn main() {
go start_server()
time.sleep(100 * time.millisecond)
ws_client('ws://127.0.0.1:30000') !
}
fn start_server() ! {
mut s := websocket.new_server(.ip6, 30000, '')
s.ping_interval = 100
s.on_connect(fn (mut s websocket.ServerClient) !bool {
// Here you can look att the client info and accept or not accept
// just returning a true/false
if s.resource_name != '/' {
panic('unexpected resource name in test')
return false
}
return true
}) !
s.on_message(fn (mut ws websocket.Client, msg &websocket.Message) ! {
ws.write(msg.payload, msg.opcode) or { panic(err) }
})
s.on_close(fn (mut ws websocket.Client, code int, reason string) ! {
println('client ($ws.id) closed connection')
})
s.listen() or { println('error on server listen: $err') }
}
fn ws_client(uri string) ! {
eprintln('connecting to $uri ...')
mut ws := websocket.new_client(uri) !
ws.on_open(fn (mut ws websocket.Client) ! {
println('open!')
ws.pong() or { panic(err) }
})
ws.on_error(fn (mut ws websocket.Client, err string) ! {
println('error: $err')
// this can be thrown by internet connection problems
})
ws.on_close(fn (mut ws websocket.Client, code int, reason string) ! {
println('closed')
})
ws.on_message(fn (mut ws websocket.Client, msg &websocket.Message) ! {
println('client got type: $msg.opcode payload:\n$msg.payload')
if msg.opcode == .text_frame {
smessage := msg.payload.bytestr()
println('Message: $smessage')
} else {
println('Binary message: $msg')
}
})
ws.connect() or { panic('fail to connect') }
go ws.listen()
text := ['a'].repeat(2)
for msg in text {
ws.write(msg.bytes(), .text_frame) or { panic('fail to write to websocket') }
// wait to give time to recieve response before send a new one
time.sleep(100 * time.millisecond)
}
// wait to give time to recieve response before asserts
time.sleep(500 * time.millisecond)
}
pub fn parse(rawurl string) !URL
pub struct URL {
pub mut:
scheme string
opaque string // encoded opaque data
user &Userinfo // username and password information
host string // host or host:port
path string // path (relative paths may omit leading slash)
raw_path string // encoded path hint (see escaped_path method)
force_query bool // append a query ('?') even if raw_query is empty
raw_query string // encoded query values, without '?'
fragment string // fragment for references, without '#'
}
struct Userinfo {
pub:
username string
password string
password_set bool
}
pub fn (u &URL) hostname() string
pub fn (u &URL) port() string
pub fn (u &URL) query() Values
pub fn parse_query(query string) !Values
struct Value {
pub mut:
data []string
}
struct Values {
pub mut:
data map[string]Value
len int
}