You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

jsync_ws.js 7.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. // FILE:WS0
  2. // TODO:JFI this file probably causes memory leaks
  3. window.glob_u.ws = window.glob_u.ws || {
  4. sockets:{},
  5. fns:{},
  6. flags:{},
  7. }
  8. window.glob_u.trc = window.glob_u.trc || {
  9. arr:[],
  10. }
  11. // TODO:JFI I should factor out my development junk
  12. function trc_sto(s,o){
  13. if (!glob_u?.prom?.init_db_resolve?.resolved){
  14. var elm = {name:s,o,timestamp:Date.now()}
  15. glob_u.trc.arr.push(elm)
  16. // clog("_trc:sto",s,o.sto_event_type,elm.timestamp,o)
  17. }
  18. }
  19. window.glob_u.ws.fns.reconnect = function reconnect(o,close_event){
  20. connect_ws(o.params)
  21. }
  22. // TODO:JFI These event handlers are less generic now
  23. window.glob_u.ws.fns.onclose = function onclose(event){
  24. clog("WS_CLOSE",{that:this,readyState:this.readyState,args:[...arguments]})
  25. // glob_u.ws.sockets.ws1.params.ord.run_cbs("WS_CLOSE:",{event,that:this})
  26. glob_u.ws.sockets[this.params.socket_name].params.ord.run_cbs("WS_CLOSE:",{event,that:this})
  27. // setTimeout(this.params.fns.reconnect,1000)
  28. let timeout0 = this.params.timeout0 || 100
  29. let timeout_multi = this.params.timeout_multi || 3000
  30. let t =timeout_multi
  31. // let now = Date.now()
  32. if (this.params.HAS_OPENED && timeout_multi<Date.now()-this.params.OPEN_TIME){
  33. t=timeout0
  34. }
  35. // clog(":TIME:",now,this.params.OPEN_TIME,now-this.params.OPEN_TIME)
  36. this.params.HAS_OPENED = 0
  37. setTimeout(this.params.fns.reconnect,t)
  38. }
  39. window.glob_u.ws.fns.onmessage = function onmessage(event){
  40. // clog("WS_MESSAGE",{that:this,args:[...arguments]})
  41. // glob_u.ws.sockets.ws1.params.ord.run_cbs("WS_MESSAGE:",{event,that:this})
  42. glob_u.ws.sockets[this.params.socket_name].params.ord.run_cbs("WS_MESSAGE:",{event,that:this})
  43. }
  44. window.glob_u.ws.fns.onerror = function onerror(event){
  45. // clog("WS_ERROR",{that:this,args:[...arguments]})
  46. // glob_u.ws.sockets.ws1.params.ord.run_cbs("WS_ERROR:",{event,that:this})
  47. glob_u.ws.sockets[this.params.socket_name].params.ord.run_cbs("WS_ERROR:",{event,that:this})
  48. }
  49. window.glob_u.ws.fns.onopen = function onopen(event){
  50. this.params.HAS_OPENED = 1
  51. this.params.OPEN_TIME = Date.now()
  52. // clog("WS_OPEN???",{that:this,args:[...arguments]},{on_open_once:this.on_open_once,on_open_cbs:this.params.on_open_cbs})
  53. // glob_u.ws.sockets.ws1.params.ord.run_cbs("WS_OPEN:",{event,that:this})
  54. glob_u.ws.sockets[this.params.socket_name].params.ord.run_cbs("WS_OPEN:",{event,that:this})
  55. return
  56. var cb
  57. if (this.on_open_once){
  58. for (cb of this.on_open_once){
  59. cb(event,this)
  60. }
  61. if (this?.params?.on_open_cbs){
  62. for (cb of this?.params?.on_open_cbs){
  63. cb(event,this)
  64. }
  65. }
  66. }
  67. }
  68. window.glob_u.ws.fns.ws_fns_factory = function ws_fns_factory(socket_opts){
  69. var socket_name = socket_opts.socket_name
  70. // const sockets =
  71. var v1 = "init"
  72. var fns = {
  73. get_socket(o){
  74. return glob_u.ws.sockets[socket_name]
  75. },
  76. reconnect(){
  77. var socket = fns.get_socket()
  78. clog("RECONNECT",socket_opts,socket,socket?.DoNotReconnect)
  79. // if (socket.DoNotReconnect || socket.params.DoNotReconnect || glob_u.ws?.flags?.DoNotReconnect){
  80. if (socket.DoNotReconnect || !socket.params.AutoReconnect || glob_u.ws?.flags?.DoNotReconnect){
  81. clog("RECONNECTION NOT ATTEMPTED",socket_opts)
  82. return
  83. } else {
  84. }
  85. connect_ws(socket_opts)
  86. },
  87. log_var(o){
  88. clog("var:",v1)
  89. return v1
  90. },
  91. set_var(val){
  92. v1 = val
  93. return v1
  94. },
  95. send_text(o){
  96. var socket = fns.get_socket()
  97. clog("send_text",{that:this,fns})
  98. socket.send(JSON.stringify(o));
  99. },
  100. jsend(o){
  101. var socket = fns.get_socket()
  102. // clog("!!!",{that:this,fns})
  103. socket.send(JSON.stringify(o));
  104. },
  105. }
  106. return fns
  107. }
  108. function connect_ws(o= {}){
  109. // clog("connect_ws:",o,jc(o))
  110. glob_u.fns.merge_partial_template(o,{on_open_cbs:[]})
  111. var sockets = window.glob_u.ws.sockets
  112. var old_socket = sockets[o.socket_name]
  113. if (old_socket && old_socket.readyState == 1){
  114. clog(`WS ${o.socket_name} is already CONNECTED:`,old_socket , o)
  115. return
  116. } else if (old_socket && (old_socket.readyState != 3 && old_socket.readyState != undefined )){
  117. clog(`WS ${o.socket_name} exsists and in not closed:`,old_socket , o)
  118. return
  119. }
  120. var socket = new WebSocket(o.url)
  121. socket.on_open_once = []
  122. socket.pre_init_msgs = []
  123. socket.params = o
  124. // if ()
  125. Object.assign(o.fns, window.glob_u.ws.fns.ws_fns_factory(o))
  126. // Object.assign(o.fns2, window.glob_u.ws.fns.ws_fns_factory(o))
  127. Object.assign(socket,o.methods)
  128. sockets[o.socket_name]=socket
  129. // o.jsend ? socket.jsend = o.jsend: 0
  130. // clog("CONNECTING WS:",{o,socket})
  131. return [socket,old_socket]
  132. }
  133. // FILE:WS1
  134. function create_ws_ord(){
  135. if (!glob_u.cb.ws){
  136. var ord = new glob_u.cls.reg_cb_ord()
  137. glob_u.cb.ws = ord
  138. glob_u.cb.ws.reg_cb = ord.reg_cb
  139. glob_u.cb.ws.run_cbs = ord.run_cbs
  140. glob_u.cb.ws.STO_EVENT = glob_u.fns.gen_ord_decs(glob_u.cb.ws,"STO_EVENT:")
  141. // glob_u.cb.ord_v1.estr = glob_u.fns.gen_ord_decs(glob_u.cb.ord_v1.ord,"")
  142. // glob_u.cb.ord_v1.run_cbs_lz = glob_u.cb.ord_v1.estr.run_cbs_lz
  143. // glob_u.cb.ord_v1.ord.run_cbs_lz = glob_u.cb.ord_v1.run_cbs_lz
  144. }
  145. }
  146. window.glob_u.ws.fns.dispatch = function dispatch(o,obj_x,info){
  147. var event = o.event
  148. // socket = o.that
  149. var data = JSON.parse(event.data)
  150. // clog("WS_dispatch",data,socket.params.ord,data["CLIENT_KEY"])
  151. // clog("trc:sto:ws_rec",data.CLIENT_KEY,data.sto_event_type,data)
  152. trc_sto("ws_rec",data)
  153. glob_u.ws.sockets.ws1.params.ord.run_cbs("WS_MESSAGE:"+data["CLIENT_KEY"],{event,that:this,data})
  154. return
  155. if (e.arguments[0].type == "message"){
  156. var data = JSON.parse(e.arguments[0].data)
  157. if ("type" in data && ws_handlers[data.type]){
  158. ws_handlers[data.type](data,{that:e.that,event:e.arguments[0]})
  159. } else {
  160. clog("NO HANDLER FOR",data.type)
  161. }
  162. clog("~WS",data,e)
  163. } else if (e.arguments[0].type == "open") {
  164. ws_handlers.on_open(e)
  165. }
  166. }
  167. function ws_reload(){
  168. try{
  169. if ((!glob_u.ws.sockets.ws1 || glob_u.ws.sockets.ws1.readyState == 3 || glob_u.ws.sockets.ws1.readyState == undefined)){
  170. ws_helper()
  171. } else {
  172. glob_u.ws.sockets.ws1.close()
  173. clog(glob_u.ws.sockets.ws1,glob_u.ws.sockets.ws1.readyState)
  174. glob_u.ws.sockets.ws1.onclose = ws_helper
  175. }
  176. } catch (err){
  177. clog(err)
  178. }
  179. }
  180. function get_room_name(){
  181. // return
  182. var s=location.search
  183. // if s[0]=="?"){}
  184. s[0]=="?" ? s = s.slice(1):0
  185. var param
  186. for (param of s.split("&")){
  187. let kv = param.split("=")
  188. if (kv[0]=="room"){
  189. return kv[1]
  190. }
  191. clog("::",param,kv)
  192. // clog("::",param,kv,"")
  193. }
  194. // var
  195. return "room_name"
  196. var room_name=location.pathname.match(/\/loc.([^\/]*)\//)
  197. if (room_name){
  198. room_name = room_name[1]
  199. } else {
  200. room_name = location.pathname.split("/").pop()
  201. }
  202. return room_name
  203. }
  204. // function get_room_name(){
  205. function get_room_name_old(){
  206. var room_name=location.pathname.match(/\/loc.([^\/]*)\//)
  207. if (room_name){
  208. room_name = room_name[1]
  209. } else {
  210. room_name = location.pathname.split("/").pop()
  211. }
  212. return room_name
  213. }
  214. function ws_helper(){
  215. clog("WS_HELPER")
  216. var fns = window.glob_u.ws.fns
  217. var o = {
  218. include_participants_data:1,
  219. include_ws_channel_data:1, // required for participants_data to work
  220. // msto.participants and masto.ws_channels will be defined in either case so we don't need to handle cases where some users enable this and some don't
  221. AutoReconnect:false,
  222. AutoReconnect:true,
  223. url:'wss://' + window.location.hostname +`/djc_srv/ws/chat/${get_room_name()}`,
  224. socket_name:"ws1",
  225. ord:glob_u.cb.ws,
  226. methods:{
  227. onmessage:fns.dispatch,
  228. onclose:fns.onclose,
  229. onerror:fns.onerror,
  230. onopen:fns.onopen,
  231. },
  232. methods:{
  233. onmessage:fns.onmessage,
  234. onclose:fns.onclose,
  235. onerror:fns.onerror,
  236. onopen:fns.onopen,
  237. },
  238. fns:{
  239. // reconnect:fns.reconnect,
  240. },
  241. }
  242. /*
  243. if (window.glob_u.ws.ws1 && window.glob_u.ws.ws1.readyState == 1){
  244. clog("WS ws1 is CONNECTED:",window.glob_u.ws.ws1)
  245. return
  246. }
  247. */
  248. var socket = connect_ws(o)
  249. // clog({socket})
  250. }
  251. window.glob_u.fns.connect_ws = connect_ws
  252. glob_u.fns.get_room_name=get_room_name
  253. create_ws_ord()
  254. glob_u.cb.ws.reg_cb(window.glob_u.ws.fns.dispatch,"WS_MESSAGE:","WS_MESSAGE")