1 | static long webSocketTimeOut = 60000; // can be changed per WebSocket |
2 | |
3 | static O eleu_webSocket_onMessage, eleu_webSocket_new; |
4 | static O eleu_webSocket_handler; |
5 | |
6 | static Set<MyWebSocket> webSockets = synchroHashSet(); |
7 | static new AtomicLong webSocketPings; |
8 | static new AtomicLong webSocketPongs; |
9 | |
10 | svoid eleu_webSocket_init { |
11 | if (nempty(webServerPorts)) pcall { |
12 | //serveHttp(webServerPort); |
13 | //serveHttpWithWebsockets(webServerPort, eleu_webSocket_handler()); |
14 | //serveHttpWithWebsockets_server.printServes = false; |
15 | serveHttpWithWebsockets_multiplePorts(eleu_webSocket_handler(), webServerPorts); |
16 | } |
17 | doEvery_daemon(5000, r cleanWebSockets); |
18 | } |
19 | |
20 | sclass MyWebSocket extends WebSocket { |
21 | L<S> msgs = synchroList(); |
22 | volatile long lastMessage = sysNow(); |
23 | S botID; |
24 | WeakReference bot; |
25 | long timeout = webSocketTimeOut; |
26 | |
27 | *(NanoHTTPD.IHTTPSession handshake) { super(handshake); } |
28 | |
29 | public void sendFrame(WebSocketFrame frame) throws IOException { |
30 | frame.write(out); |
31 | // assume write worked? |
32 | lastMessage = sysNow(); |
33 | } |
34 | |
35 | protected void onPong(WebSocketFrame pongFrame) { |
36 | // don't use WebSocket ping/pong - it doesn't work |
37 | } |
38 | |
39 | protected void onMessage(WebSocketFrame messageFrame) { |
40 | //print("websocket msg: " + messageFrame.getTextPayload()); |
41 | lastMessage = sysNow(); |
42 | S s = messageFrame.getTextPayload(); |
43 | if (eq(s, "ping")) incAtomicLong(webSocketPongs); |
44 | pcall { |
45 | if (botID != null) |
46 | call(getBot(botID), 'onWebSocketMessage, this, s); |
47 | else { |
48 | msgs.add(s); |
49 | callF(eleu_webSocket_onMessage, this, s); |
50 | } |
51 | } |
52 | } |
53 | |
54 | protected void onClose(WebSocketFrame.CloseCode code, String reason, boolean initiatedByRemote) { |
55 | //print("websocket close"); |
56 | _removeMe(); |
57 | } |
58 | protected void onException(IOException e) { printStackTrace(e); } |
59 | |
60 | void _removeMe() { |
61 | webSockets.remove(this); |
62 | if (botID != null) |
63 | pcall(getBot(botID), 'onWebSocketClosed, this); |
64 | } |
65 | |
66 | void closeMe() ctex { |
67 | _removeMe(); |
68 | close(WebSocketFrame.CloseCode.NormalClosure, ""); |
69 | } |
70 | |
71 | void clean() { |
72 | if (timeout > 0 && sysNow() >= lastMessage + timeout) { |
73 | print("Timing out web socket for bot " + botID); |
74 | _removeMe(); |
75 | pcall { close(WebSocketFrame.CloseCode.NormalClosure, "timeout"); } |
76 | } |
77 | } |
78 | } |
79 | |
80 | static O eleu_webSocket_handler() { |
81 | if (eleu_webSocket_handler == null) |
82 | eleu_webSocket_handler = func(final NanoHTTPD.IHTTPSession handshake) { |
83 | MyWebSocket ws = new(handshake); |
84 | S uri = handshake.getUri(); |
85 | print("WebSocket URI: " + uri); |
86 | webSockets.add(ws); |
87 | bool dispatched = false; |
88 | try { |
89 | uri = dropPrefix("/", uri); |
90 | int i = smartIndexOf(uri, '/'); |
91 | S botID = takeFirst(i, uri); |
92 | if (isInteger(botID)) { |
93 | botID = fsI(botID); |
94 | dispatched = true; |
95 | O bot = getBot(botID); |
96 | if (bot == null) fail("Bot not found: " + botID); |
97 | ws.bot = new WeakReference(bot); |
98 | call(bot, 'onNewWebSocket, ws, or2(substring(uri, i), "/")); |
99 | print("WebSocket dispatched to " + botID); |
100 | ws.botID = botID; |
101 | } |
102 | } catch e { |
103 | printException(e); |
104 | ws.closeMe(); |
105 | null; |
106 | } |
107 | if (!dispatched) |
108 | pcallF(eleu_webSocket_new, ws); |
109 | ret ws; |
110 | }; |
111 | ret eleu_webSocket_handler; |
112 | } |
113 | |
114 | static void cleanWebSockets() { |
115 | for (MyWebSocket ws : cloneList(webSockets)) ws.clean(); |
116 | } |
download show line numbers debug dex old transpilations
Travelled to 15 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, irmadwmeruwu, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, onxytkatvevr, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt
No comments. add comment
Snippet ID: | #1013904 |
Snippet name: | Eleu WebSocket Include |
Eternal ID of this version: | #1013904/34 |
Text MD5: | 7cd2fdb0677ccb55ffe34c195a8d2c54 |
Author: | stefan |
Category: | javax / web |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2022-03-30 18:46:32 |
Source code size: | 3548 bytes / 116 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 442 / 1207 |
Version history: | 33 change(s) |
Referenced in: | [show references] |