| 1 | // vtest build: present_openssl? |
| 2 | module main |
| 3 | |
| 4 | import time |
| 5 | import term |
| 6 | import net.websocket |
| 7 | |
| 8 | fn main() { |
| 9 | spawn start_server() |
| 10 | time.sleep(100 * time.millisecond) |
| 11 | start_client()! |
| 12 | } |
| 13 | |
| 14 | fn slog(message string) { |
| 15 | eprintln(term.colorize(term.bright_yellow, message)) |
| 16 | } |
| 17 | |
| 18 | fn clog(message string) { |
| 19 | eprintln(term.colorize(term.cyan, message)) |
| 20 | } |
| 21 | |
| 22 | fn wlog(message string) { |
| 23 | eprintln(term.colorize(term.bright_blue, message)) |
| 24 | } |
| 25 | |
| 26 | // start_server starts the websocket server, it receives messages |
| 27 | // and send it back to the client that sent it |
| 28 | fn start_server() ! { |
| 29 | mut s := websocket.new_server(.ip6, 30000, '') |
| 30 | defer { |
| 31 | unsafe { |
| 32 | s.free() |
| 33 | } |
| 34 | } |
| 35 | // Make that in execution test time give time to execute at least one time |
| 36 | s.set_ping_interval(100) |
| 37 | s.on_connect(fn (mut s websocket.ServerClient) !bool { |
| 38 | slog('ws.on_connect, s.client_key: ${s.client_key}') |
| 39 | // Here you can look att the client info and accept or not accept |
| 40 | // just returning a true/false |
| 41 | if s.resource_name != '/' { |
| 42 | return false |
| 43 | } |
| 44 | return true |
| 45 | })! |
| 46 | s.on_message(fn (mut ws websocket.Client, msg &websocket.Message) ! { |
| 47 | slog('s.on_message msg.opcode: ${msg.opcode} | msg.payload: ${msg.payload}') |
| 48 | ws.write(msg.payload, msg.opcode) or { |
| 49 | eprintln('ws.write err: ${err}') |
| 50 | return err |
| 51 | } |
| 52 | }) |
| 53 | s.on_close(fn (mut ws websocket.Client, code int, reason string) ! { |
| 54 | slog('s.on_close code: ${code}, reason: ${reason}') |
| 55 | // println('client (${ws.id}) closed connection') |
| 56 | }) |
| 57 | s.listen() or { |
| 58 | slog('s.listen err: ${err}') |
| 59 | return err |
| 60 | } |
| 61 | slog('s.listen finished') |
| 62 | } |
| 63 | |
| 64 | // start_client starts the websocket client, it writes a message to |
| 65 | // the server and prints all the messages received |
| 66 | fn start_client() ! { |
| 67 | mut ws := websocket.new_client('ws://localhost:30000')! |
| 68 | defer { |
| 69 | unsafe { |
| 70 | ws.free() |
| 71 | } |
| 72 | } |
| 73 | // mut ws := websocket.new_client('wss://echo.websocket.org:443')? |
| 74 | // use on_open_ref if you want to send any reference object |
| 75 | ws.on_open(fn (mut ws websocket.Client) ! { |
| 76 | clog('ws.on_open') |
| 77 | }) |
| 78 | // use on_error_ref if you want to send any reference object |
| 79 | ws.on_error(fn (mut ws websocket.Client, err string) ! { |
| 80 | clog('ws.on_error error: ${err}') |
| 81 | }) |
| 82 | // use on_close_ref if you want to send any reference object |
| 83 | ws.on_close(fn (mut ws websocket.Client, code int, reason string) ! { |
| 84 | clog('ws.on_close') |
| 85 | }) |
| 86 | // use on_message_ref if you want to send any reference object |
| 87 | ws.on_message(fn (mut ws websocket.Client, msg &websocket.Message) ! { |
| 88 | if msg.payload.len > 0 { |
| 89 | message := msg.payload.bytestr() |
| 90 | clog('ws.on_message client got type: ${msg.opcode} payload: `${message}`') |
| 91 | } |
| 92 | }) |
| 93 | // you can add any pointer reference to use in callback |
| 94 | // t := TestRef{count: 10} |
| 95 | // ws.on_message_ref(fn (mut ws websocket.Client, msg &websocket.Message, r &SomeRef) ? { |
| 96 | // // eprintln('type: ${msg.opcode} payload:\n${msg.payload} ref: ${r}') |
| 97 | // }, &r) |
| 98 | ws.connect() or { |
| 99 | clog('ws.connect err: ${err}') |
| 100 | return err |
| 101 | } |
| 102 | clog('ws.connect succeeded') |
| 103 | spawn write_echo(mut ws) // or { println('error on write_echo ${err}') } |
| 104 | ws.listen() or { |
| 105 | clog('ws.listen err: ${err}') |
| 106 | return err |
| 107 | } |
| 108 | clog('ws.listen finished') |
| 109 | } |
| 110 | |
| 111 | fn write_echo(mut ws websocket.Client) ! { |
| 112 | wlog('write_echo, start') |
| 113 | message := 'echo this' |
| 114 | for i := 0; i <= 5; i++ { |
| 115 | // Server will send pings every 30 seconds |
| 116 | wlog('write_echo, writing message: `${message}` ...') |
| 117 | ws.write_string(message) or { |
| 118 | wlog('write_echo, ws.write_string err: ${err}') |
| 119 | return err |
| 120 | } |
| 121 | time.sleep(100 * time.millisecond) |
| 122 | } |
| 123 | ws.close(1000, 'normal') or { |
| 124 | wlog('write_echo, close err: ${err}') |
| 125 | return err |
| 126 | } |
| 127 | wlog('write_echo, done') |
| 128 | } |
| 129 | |