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: | 672 / 1445 |
| Version history: | 33 change(s) |
| Referenced in: | [show references] |