Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

116
LINES

< > BotCompany Repo | #1013904 // Eleu WebSocket Include

JavaX fragment (include)

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