@noita-ts/pollnet 0.3.8 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api.d.ts +221 -0
- package/dist/api.lua +490 -0
- package/dist/index.d.ts +53 -211
- package/dist/index.lua +171 -490
- package/dist/lualib_bundle.lua +7 -211
- package/package.json +4 -4
- package/dist/async.d.ts +0 -76
- package/dist/async.lua +0 -167
package/dist/index.lua
CHANGED
|
@@ -1,490 +1,171 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
local
|
|
7
|
-
|
|
8
|
-
local
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
local
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
local
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
local
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
end
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
ret_body_only = not not ret_body_only
|
|
173
|
-
return self:_open(
|
|
174
|
-
pollnet.pollnet_simple_http_get,
|
|
175
|
-
url,
|
|
176
|
-
headers,
|
|
177
|
-
ret_body_only
|
|
178
|
-
)
|
|
179
|
-
end
|
|
180
|
-
|
|
181
|
-
function socket_mt:http_post(url, headers, body, ret_body_only)
|
|
182
|
-
body = body or ""
|
|
183
|
-
headers = format_headers(headers or {
|
|
184
|
-
["content-type"] = "application/x-www-form-urlencoded"
|
|
185
|
-
})
|
|
186
|
-
ret_body_only = not not ret_body_only
|
|
187
|
-
return self:_open(
|
|
188
|
-
pollnet.pollnet_simple_http_post,
|
|
189
|
-
url,
|
|
190
|
-
headers,
|
|
191
|
-
body,
|
|
192
|
-
#body,
|
|
193
|
-
ret_body_only
|
|
194
|
-
)
|
|
195
|
-
end
|
|
196
|
-
|
|
197
|
-
function socket_mt:open_ws(url)
|
|
198
|
-
return self:_open(pollnet.pollnet_open_ws, url)
|
|
199
|
-
end
|
|
200
|
-
|
|
201
|
-
function socket_mt:open_tcp(addr)
|
|
202
|
-
return self:_open(pollnet.pollnet_open_tcp, addr)
|
|
203
|
-
end
|
|
204
|
-
|
|
205
|
-
function socket_mt:serve_http(addr, dir)
|
|
206
|
-
self.is_http_server = true
|
|
207
|
-
if dir and dir ~= "" then
|
|
208
|
-
return self:_open(pollnet.pollnet_serve_static_http, addr, dir)
|
|
209
|
-
else
|
|
210
|
-
return self:_open(pollnet.pollnet_serve_http, addr)
|
|
211
|
-
end
|
|
212
|
-
end
|
|
213
|
-
|
|
214
|
-
function socket_mt:add_virtual_file(filename, filedata)
|
|
215
|
-
assert(filedata and type(filedata) == 'string', "filedata must be provided as string!")
|
|
216
|
-
if filename:sub(1,1) ~= "/" then
|
|
217
|
-
-- url paths start from root at "/"
|
|
218
|
-
filename = "/" .. filename
|
|
219
|
-
end
|
|
220
|
-
local dsize = #filedata
|
|
221
|
-
pollnet.pollnet_add_virtual_file(_ctx, self._socket, filename, filedata, dsize)
|
|
222
|
-
end
|
|
223
|
-
|
|
224
|
-
function socket_mt:remove_virtual_file(filename)
|
|
225
|
-
pollnet.pollnet_remove_virtual_file(_ctx, self._socket, filename)
|
|
226
|
-
end
|
|
227
|
-
|
|
228
|
-
function socket_mt:listen_ws(addr, callback)
|
|
229
|
-
if callback then self:on_connection(callback) end
|
|
230
|
-
return self:_open(pollnet.pollnet_listen_ws, addr)
|
|
231
|
-
end
|
|
232
|
-
|
|
233
|
-
function socket_mt:listen_tcp(addr, callback)
|
|
234
|
-
if callback then self:on_connection(callback) end
|
|
235
|
-
return self:_open(pollnet.pollnet_listen_tcp, addr)
|
|
236
|
-
end
|
|
237
|
-
|
|
238
|
-
function socket_mt:serve_dynamic_http(addr, keep_alive, callback)
|
|
239
|
-
if callback then self:on_connection(callback) end
|
|
240
|
-
return self:_open(pollnet.pollnet_serve_dynamic_http, addr, keep_alive or false)
|
|
241
|
-
end
|
|
242
|
-
|
|
243
|
-
function socket_mt:on_connection(f)
|
|
244
|
-
self._on_connection = f
|
|
245
|
-
return self
|
|
246
|
-
end
|
|
247
|
-
|
|
248
|
-
function socket_mt:_get_message()
|
|
249
|
-
local msg_size = pollnet.pollnet_get_data_size(_ctx, self._socket)
|
|
250
|
-
if msg_size > 0 then
|
|
251
|
-
-- Note: unsafe_get_data_ptr requires careful consideration to use safely!
|
|
252
|
-
-- Here we are OK because ffi.string copies the data to a new Lua string,
|
|
253
|
-
-- so we only hang on to the pointer long enough for the copy.
|
|
254
|
-
local raw_pointer = pollnet.pollnet_unsafe_get_data_ptr(_ctx, self._socket)
|
|
255
|
-
if raw_pointer == nil then
|
|
256
|
-
error("Impossible situation: msg_size > 0 but null data pointer")
|
|
257
|
-
end
|
|
258
|
-
return ffi.string(raw_pointer, msg_size)
|
|
259
|
-
else
|
|
260
|
-
return ""
|
|
261
|
-
end
|
|
262
|
-
end
|
|
263
|
-
|
|
264
|
-
function socket_mt:poll()
|
|
265
|
-
self._last_message = nil
|
|
266
|
-
if not self._socket then
|
|
267
|
-
self._status = "invalid"
|
|
268
|
-
return false, "invalid"
|
|
269
|
-
end
|
|
270
|
-
local res = POLLNET_RESULT_CODES[pollnet.pollnet_update(_ctx, self._socket)] or "error"
|
|
271
|
-
self._status = res
|
|
272
|
-
if res == "hasdata" then
|
|
273
|
-
self._status = "open"
|
|
274
|
-
self._last_message = self:_get_message()
|
|
275
|
-
return true, self._last_message
|
|
276
|
-
elseif res == "nodata" then
|
|
277
|
-
self._status = "open"
|
|
278
|
-
return true
|
|
279
|
-
elseif res == "opening" then
|
|
280
|
-
self._status = "opening"
|
|
281
|
-
return true
|
|
282
|
-
elseif res == "error" then
|
|
283
|
-
self._status = "error"
|
|
284
|
-
self._last_message = self:_get_message()
|
|
285
|
-
return false, self._last_message
|
|
286
|
-
elseif res == "closed" then
|
|
287
|
-
self._status = "closed"
|
|
288
|
-
self._last_message = "closed"
|
|
289
|
-
return false, "closed"
|
|
290
|
-
elseif res == "newclient" then
|
|
291
|
-
self._status = "open"
|
|
292
|
-
local client_addr = self:_get_message()
|
|
293
|
-
local client_handle = pollnet.pollnet_get_connected_client_handle(_ctx, self._socket)
|
|
294
|
-
assert(client_handle > 0)
|
|
295
|
-
local client_sock = Socket():_from_handle(client_handle)
|
|
296
|
-
client_sock.parent = self
|
|
297
|
-
client_sock.remote_addr = client_addr
|
|
298
|
-
if self._on_connection then
|
|
299
|
-
self._on_connection(client_sock, client_addr)
|
|
300
|
-
else
|
|
301
|
-
print("Incoming connection but no :on_connection handler! Just closing it!")
|
|
302
|
-
client_sock:close()
|
|
303
|
-
end
|
|
304
|
-
return true
|
|
305
|
-
end
|
|
306
|
-
end
|
|
307
|
-
|
|
308
|
-
function socket_mt:await()
|
|
309
|
-
local yield_count = 0
|
|
310
|
-
while true do
|
|
311
|
-
if self.timeout and (yield_count > self.timeout) then
|
|
312
|
-
return false, "timeout"
|
|
313
|
-
end
|
|
314
|
-
local happy, msg = self:poll()
|
|
315
|
-
if not happy then
|
|
316
|
-
self:close()
|
|
317
|
-
return false, "error: " .. tostring(msg)
|
|
318
|
-
end
|
|
319
|
-
if msg then return msg end
|
|
320
|
-
yield_count = yield_count + 1
|
|
321
|
-
coroutine.yield()
|
|
322
|
-
end
|
|
323
|
-
end
|
|
324
|
-
|
|
325
|
-
function socket_mt:await_n(count)
|
|
326
|
-
local parts = {}
|
|
327
|
-
for idx = 1, count do
|
|
328
|
-
local part, err = self:await()
|
|
329
|
-
if not part then return false, err end
|
|
330
|
-
parts[idx] = part
|
|
331
|
-
end
|
|
332
|
-
return parts
|
|
333
|
-
end
|
|
334
|
-
|
|
335
|
-
function socket_mt:last_message()
|
|
336
|
-
return self._last_message
|
|
337
|
-
end
|
|
338
|
-
|
|
339
|
-
function socket_mt:status()
|
|
340
|
-
return self._status
|
|
341
|
-
end
|
|
342
|
-
|
|
343
|
-
function socket_mt:send(msg)
|
|
344
|
-
assert(self._socket)
|
|
345
|
-
assert(type(msg) == 'string', "Argument to send must be a string")
|
|
346
|
-
pollnet.pollnet_send(_ctx, self._socket, msg)
|
|
347
|
-
end
|
|
348
|
-
|
|
349
|
-
function socket_mt:send_binary(msg)
|
|
350
|
-
assert(self._socket)
|
|
351
|
-
assert(type(msg) == 'string', "Argument to send must be a string")
|
|
352
|
-
pollnet.pollnet_send_binary(_ctx, self._socket, msg, #msg)
|
|
353
|
-
end
|
|
354
|
-
|
|
355
|
-
function socket_mt:close()
|
|
356
|
-
if not self._socket then return end
|
|
357
|
-
pollnet.pollnet_close(_ctx, self._socket)
|
|
358
|
-
self._socket = nil
|
|
359
|
-
end
|
|
360
|
-
|
|
361
|
-
local function get_nanoid()
|
|
362
|
-
local _id_scratch = ffi.new("int8_t[?]", 128)
|
|
363
|
-
local msg_size = pollnet.pollnet_get_nanoid(_id_scratch, 128)
|
|
364
|
-
return ffi.string(_id_scratch, msg_size)
|
|
365
|
-
end
|
|
366
|
-
|
|
367
|
-
local function sleep_ms(ms)
|
|
368
|
-
pollnet.pollnet_sleep_ms(ms)
|
|
369
|
-
end
|
|
370
|
-
|
|
371
|
-
local reactor_mt = {}
|
|
372
|
-
local function Reactor()
|
|
373
|
-
local ret = setmetatable({}, {__index = reactor_mt})
|
|
374
|
-
ret:init()
|
|
375
|
-
return ret
|
|
376
|
-
end
|
|
377
|
-
|
|
378
|
-
function reactor_mt:init()
|
|
379
|
-
self.threads = {}
|
|
380
|
-
end
|
|
381
|
-
|
|
382
|
-
function reactor_mt:run(thread_body)
|
|
383
|
-
local thread = coroutine.create(function()
|
|
384
|
-
thread_body(self)
|
|
385
|
-
end)
|
|
386
|
-
self.threads[thread] = true
|
|
387
|
-
end
|
|
388
|
-
|
|
389
|
-
function reactor_mt:run_server(server_sock, client_body)
|
|
390
|
-
server_sock:on_connection(function(client_sock, addr)
|
|
391
|
-
self:run(function()
|
|
392
|
-
client_body(client_sock, addr)
|
|
393
|
-
end)
|
|
394
|
-
end)
|
|
395
|
-
self:run(function()
|
|
396
|
-
while true do server_sock:await() end
|
|
397
|
-
end)
|
|
398
|
-
end
|
|
399
|
-
|
|
400
|
-
function reactor_mt:log(...)
|
|
401
|
-
print(...)
|
|
402
|
-
end
|
|
403
|
-
|
|
404
|
-
function reactor_mt:update()
|
|
405
|
-
local live_count = 0
|
|
406
|
-
local cur_threads = self.threads
|
|
407
|
-
self.threads = {}
|
|
408
|
-
for thread, _ in pairs(cur_threads) do
|
|
409
|
-
if coroutine.status(thread) == "dead" then
|
|
410
|
-
cur_threads[thread] = nil
|
|
411
|
-
else
|
|
412
|
-
live_count = live_count + 1
|
|
413
|
-
local happy, err = coroutine.resume(thread)
|
|
414
|
-
if not happy then self:log("Error", err) end
|
|
415
|
-
end
|
|
416
|
-
end
|
|
417
|
-
for thread, _ in pairs(self.threads) do
|
|
418
|
-
live_count = live_count + 1
|
|
419
|
-
cur_threads[thread] = true
|
|
420
|
-
end
|
|
421
|
-
self.threads = cur_threads
|
|
422
|
-
return live_count
|
|
423
|
-
end
|
|
424
|
-
|
|
425
|
-
local function invoke_handler(handler, req, expose_errors)
|
|
426
|
-
local happy, res = pcall(handler, req)
|
|
427
|
-
if happy then
|
|
428
|
-
return res
|
|
429
|
-
else
|
|
430
|
-
return {
|
|
431
|
-
status = "500",
|
|
432
|
-
body = (expose_errors and tostring(res)) or "Internal Error"
|
|
433
|
-
}
|
|
434
|
-
end
|
|
435
|
-
end
|
|
436
|
-
|
|
437
|
-
local function wrap_req_handler(handler, expose_errors)
|
|
438
|
-
return function(req_sock, addr)
|
|
439
|
-
while true do
|
|
440
|
-
local raw_req = req_sock:await_n(3)
|
|
441
|
-
if not raw_req then break end
|
|
442
|
-
local method, path, query = parse_method(raw_req[1])
|
|
443
|
-
local headers = parse_headers(raw_req[2])
|
|
444
|
-
local reply = invoke_handler(handler, {
|
|
445
|
-
addr = addr,
|
|
446
|
-
method = method,
|
|
447
|
-
path = path,
|
|
448
|
-
query = query,
|
|
449
|
-
headers = headers,
|
|
450
|
-
body = raw_req[3],
|
|
451
|
-
raw = raw_req
|
|
452
|
-
}, expose_errors)
|
|
453
|
-
req_sock:send(reply.status or "404")
|
|
454
|
-
req_sock:send(format_headers(reply.headers or {}))
|
|
455
|
-
req_sock:send_binary(reply.body or "")
|
|
456
|
-
end
|
|
457
|
-
req_sock:close()
|
|
458
|
-
end
|
|
459
|
-
end
|
|
460
|
-
|
|
461
|
-
local exports = {
|
|
462
|
-
VERSION = POLLNET_VERSION,
|
|
463
|
-
init = init_ctx,
|
|
464
|
-
init_hack_static = init_ctx_hack_static,
|
|
465
|
-
shutdown = shutdown_ctx,
|
|
466
|
-
Socket = Socket,
|
|
467
|
-
Reactor = Reactor,
|
|
468
|
-
pollnet = pollnet,
|
|
469
|
-
nanoid = get_nanoid,
|
|
470
|
-
sleep_ms = sleep_ms,
|
|
471
|
-
format_headers = format_headers,
|
|
472
|
-
parse_headers = parse_headers,
|
|
473
|
-
parse_method = parse_method,
|
|
474
|
-
wrap_req_handler = wrap_req_handler
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
local fnames = {
|
|
478
|
-
"open_ws", "listen_ws", "open_tcp", "listen_tcp",
|
|
479
|
-
"serve_http", "serve_dynamic_http", "http_get", "http_post"
|
|
480
|
-
}
|
|
481
|
-
for _, name in ipairs(fnames) do
|
|
482
|
-
exports[name] = function(...)
|
|
483
|
-
local sock = Socket()
|
|
484
|
-
return sock[name](sock, ...)
|
|
485
|
-
end
|
|
486
|
-
end
|
|
487
|
-
|
|
488
|
-
exports.default = exports
|
|
489
|
-
|
|
490
|
-
return exports
|
|
1
|
+
local ____lualib = require("lualib_bundle")
|
|
2
|
+
local __TS__Class = ____lualib.__TS__Class
|
|
3
|
+
local Error = ____lualib.Error
|
|
4
|
+
local RangeError = ____lualib.RangeError
|
|
5
|
+
local ReferenceError = ____lualib.ReferenceError
|
|
6
|
+
local SyntaxError = ____lualib.SyntaxError
|
|
7
|
+
local TypeError = ____lualib.TypeError
|
|
8
|
+
local URIError = ____lualib.URIError
|
|
9
|
+
local __TS__New = ____lualib.__TS__New
|
|
10
|
+
local __TS__StringSplit = ____lualib.__TS__StringSplit
|
|
11
|
+
local __TS__ArrayIsArray = ____lualib.__TS__ArrayIsArray
|
|
12
|
+
local ____exports = {}
|
|
13
|
+
local ____api = require("api")
|
|
14
|
+
local pollnet = ____api.default
|
|
15
|
+
____exports.HttpResponse = __TS__Class()
|
|
16
|
+
local HttpResponse = ____exports.HttpResponse
|
|
17
|
+
HttpResponse.name = "HttpResponse"
|
|
18
|
+
function HttpResponse.prototype.____constructor(self, status, headers, body)
|
|
19
|
+
self.status = status
|
|
20
|
+
self.headers = headers
|
|
21
|
+
self.body = body
|
|
22
|
+
end
|
|
23
|
+
function HttpResponse.read(self, socket)
|
|
24
|
+
local msgs, ____error = socket:await_n(3)
|
|
25
|
+
if not msgs then
|
|
26
|
+
error(
|
|
27
|
+
__TS__New(Error, "socket error: " .. ____error),
|
|
28
|
+
0
|
|
29
|
+
)
|
|
30
|
+
end
|
|
31
|
+
local statusStr, headersStr, respBody = unpack(msgs, 1, 3)
|
|
32
|
+
local status = tonumber((string.match(statusStr, "^%d+"))) or 500
|
|
33
|
+
return __TS__New(____exports.HttpResponse, status, headersStr, respBody)
|
|
34
|
+
end
|
|
35
|
+
function HttpResponse.prototype.parseHeaders(self)
|
|
36
|
+
local headers = {}
|
|
37
|
+
for ____, line in ipairs(__TS__StringSplit(self.headers, "\n")) do
|
|
38
|
+
do
|
|
39
|
+
local key, value = unpack(
|
|
40
|
+
__TS__StringSplit(line, ": ", 2),
|
|
41
|
+
1,
|
|
42
|
+
2
|
|
43
|
+
)
|
|
44
|
+
if not key or not value then
|
|
45
|
+
goto __continue6
|
|
46
|
+
end
|
|
47
|
+
local prev = headers[key]
|
|
48
|
+
if not prev then
|
|
49
|
+
headers[key] = value
|
|
50
|
+
goto __continue6
|
|
51
|
+
end
|
|
52
|
+
if __TS__ArrayIsArray(prev) then
|
|
53
|
+
prev[#prev + 1] = value
|
|
54
|
+
else
|
|
55
|
+
headers[key] = {prev, value}
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
::__continue6::
|
|
59
|
+
end
|
|
60
|
+
return headers
|
|
61
|
+
end
|
|
62
|
+
--- Tiny async HTTP client built on top of a {@link Scheduler}.
|
|
63
|
+
--
|
|
64
|
+
-- Requests run in coroutines and resolve to an {@link HttpResponse}.
|
|
65
|
+
____exports.HttpClient = __TS__Class()
|
|
66
|
+
local HttpClient = ____exports.HttpClient
|
|
67
|
+
HttpClient.name = "HttpClient"
|
|
68
|
+
function HttpClient.prototype.____constructor(self, scheduler)
|
|
69
|
+
self.scheduler = scheduler
|
|
70
|
+
end
|
|
71
|
+
function HttpClient.prototype.get(self, url, headers)
|
|
72
|
+
return self.scheduler:spawn(function() return ____exports.HttpResponse:read(pollnet.http_get(url, headers, false)) end)
|
|
73
|
+
end
|
|
74
|
+
function HttpClient.prototype.post(self, url, headers, body)
|
|
75
|
+
return self.scheduler:spawn(function() return ____exports.HttpResponse:read(pollnet.http_post(url, headers, body, false)) end)
|
|
76
|
+
end
|
|
77
|
+
--- Async WebSocket client built on top of an {@link AsyncReactor }.
|
|
78
|
+
-- Messages are delivered via the `onmessage` callback, and errors via
|
|
79
|
+
-- `onerror`.
|
|
80
|
+
-- Call {@link send} to send a message, and {@link close} to close the
|
|
81
|
+
-- connection and cleanup.
|
|
82
|
+
____exports.WebSocket = __TS__Class()
|
|
83
|
+
local WebSocket = ____exports.WebSocket
|
|
84
|
+
WebSocket.name = "WebSocket"
|
|
85
|
+
function WebSocket.prototype.____constructor(self, scheduler, url)
|
|
86
|
+
self.timeout = 3600
|
|
87
|
+
self.onmessage = nil
|
|
88
|
+
self.onerror = nil
|
|
89
|
+
self.socket = pollnet.open_ws(url)
|
|
90
|
+
scheduler:spawn(function()
|
|
91
|
+
local timer = 0
|
|
92
|
+
while not not self.socket do
|
|
93
|
+
do
|
|
94
|
+
local ok = true
|
|
95
|
+
local msg
|
|
96
|
+
while true do
|
|
97
|
+
ok, msg = self.socket:poll()
|
|
98
|
+
if not ok or not msg then
|
|
99
|
+
break
|
|
100
|
+
end
|
|
101
|
+
timer = 0
|
|
102
|
+
local ____opt_0 = self.onmessage
|
|
103
|
+
if ____opt_0 ~= nil then
|
|
104
|
+
____opt_0(msg)
|
|
105
|
+
end
|
|
106
|
+
if not self.socket then
|
|
107
|
+
return
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
local ____ok_2 = ok
|
|
111
|
+
if ____ok_2 then
|
|
112
|
+
timer = timer + 1
|
|
113
|
+
____ok_2 = timer < self.timeout
|
|
114
|
+
end
|
|
115
|
+
if ____ok_2 then
|
|
116
|
+
coroutine.yield()
|
|
117
|
+
goto __continue19
|
|
118
|
+
end
|
|
119
|
+
timer = 0
|
|
120
|
+
self.socket:close()
|
|
121
|
+
local ____opt_3 = self.onerror
|
|
122
|
+
if ____opt_3 ~= nil then
|
|
123
|
+
____opt_3(msg or "timeout")
|
|
124
|
+
end
|
|
125
|
+
do
|
|
126
|
+
local i = 0
|
|
127
|
+
while i < 60 do
|
|
128
|
+
coroutine.yield()
|
|
129
|
+
i = i + 1
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
if not not self.socket then
|
|
133
|
+
self.socket = pollnet.open_ws(url)
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
::__continue19::
|
|
137
|
+
end
|
|
138
|
+
end)
|
|
139
|
+
end
|
|
140
|
+
function WebSocket.prototype.send(self, message)
|
|
141
|
+
local ____opt_5 = self.socket
|
|
142
|
+
if ____opt_5 ~= nil then
|
|
143
|
+
____opt_5:send(message)
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
function WebSocket.prototype.sendBinary(self, data)
|
|
147
|
+
local ____opt_7 = self.socket
|
|
148
|
+
if ____opt_7 ~= nil then
|
|
149
|
+
____opt_7:send_binary(data)
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
function WebSocket.prototype.close(self)
|
|
153
|
+
local ____opt_9 = self.socket
|
|
154
|
+
if ____opt_9 ~= nil then
|
|
155
|
+
____opt_9:close()
|
|
156
|
+
end
|
|
157
|
+
self.socket = nil
|
|
158
|
+
end
|
|
159
|
+
____exports.runServer = function(scheduler, serverSocket, clientBody)
|
|
160
|
+
serverSocket:on_connection(function(clientSocket, addr)
|
|
161
|
+
scheduler:spawn(function() return clientBody(clientSocket, addr) end):catch(function(____, e)
|
|
162
|
+
print((("Error in client handler for " .. addr) .. ": ") .. tostring(e))
|
|
163
|
+
clientSocket:close()
|
|
164
|
+
end)
|
|
165
|
+
end)
|
|
166
|
+
scheduler:spawn(function()
|
|
167
|
+
while (serverSocket:await()) do
|
|
168
|
+
end
|
|
169
|
+
end)
|
|
170
|
+
end
|
|
171
|
+
return ____exports
|