izuemon commited on
Commit
cae42e0
·
verified ·
1 Parent(s): c4c5412

Update get_msg.py

Browse files
Files changed (1) hide show
  1. get_msg.py +77 -10
get_msg.py CHANGED
@@ -25,7 +25,8 @@ ACCOUNT_WS_URL = (
25
  "?platform=web&EIO=4&transport=websocket"
26
  )
27
 
28
- HEARTBEAT_INTERVAL = 30.0
 
29
  TOKEN_CHECK_INTERVAL = 1.0
30
  REQUEST_TIMEOUT = 30.0
31
 
@@ -348,6 +349,7 @@ def send_account_connect(ws: LoggingWS, session_token: str) -> None:
348
 
349
 
350
  def send_refresh(ws: LoggingWS, session_token: str) -> None:
 
351
  message = (
352
  '42/desk/account,0'
353
  + json.dumps(
@@ -360,6 +362,25 @@ def send_refresh(ws: LoggingWS, session_token: str) -> None:
360
  ws.send(message)
361
 
362
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
363
  def send_heartbeat(ws: LoggingWS, manager_id: str) -> None:
364
  message = (
365
  '42/desk/channel,'
@@ -450,6 +471,7 @@ def channel_worker(
450
  channel_id: str,
451
  manager_id: str,
452
  stop_event: threading.Event,
 
453
  ) -> None:
454
  try:
455
  ws = open_channel_ws(session_token, channel_id)
@@ -457,14 +479,36 @@ def channel_worker(
457
  log("CHANNEL", f"接続失敗: {exc!r}")
458
  return
459
 
460
- last_heartbeat = time.monotonic()
 
 
 
 
 
 
461
  log("SOCKET", "Channel 待機中...")
462
  try:
463
  while not stop_event.is_set():
464
  now = time.monotonic()
465
- if now - last_heartbeat >= HEARTBEAT_INTERVAL:
 
 
 
 
 
 
 
466
  send_heartbeat(ws, manager_id)
467
- last_heartbeat = now
 
 
 
 
 
 
 
 
 
468
 
469
  try:
470
  packet = ws.recv()
@@ -487,8 +531,15 @@ def channel_worker(
487
  if namespace == "/desk/channel" and payload:
488
  event_name = payload[0]
489
  log("SOCKET", f"event={event_name}")
490
- if event_name == "create":
 
 
 
 
491
  print_create_message(payload)
 
 
 
492
  except Exception as exc:
493
  log("CHANNEL", f"エラーで終了: {exc!r}")
494
  finally:
@@ -514,7 +565,10 @@ def account_worker(
514
  if now - last_token_check >= TOKEN_CHECK_INTERVAL:
515
  current_tokens = client.get_tokens() or {}
516
  current_session_token = current_tokens.get("x-account")
517
- if current_session_token and current_session_token != token_holder["token"]:
 
 
 
518
  log("AUTH", "x-account 変更検出 -> refresh 送信")
519
  send_refresh(ws, current_session_token)
520
  token_holder["token"] = current_session_token
@@ -572,20 +626,33 @@ def run() -> None:
572
  tokens = client.get_tokens()
573
  if not tokens:
574
  raise RuntimeError("get_tokens() が空でした。")
575
- required = ("ch-session-1", "ch-veil-id", "x-account", "x-account-refresh")
 
 
 
 
 
576
  missing = [k for k in required if not tokens.get(k)]
577
  if missing:
578
- raise RuntimeError("必要なトークンが取得できません: " + ", ".join(missing))
 
 
579
 
580
  manager_id, channel_id = fetch_ids(tokens)
581
  token_holder = {"token": tokens["x-account"]}
582
 
583
  stop_event = threading.Event()
584
 
585
- # channel 側を先に起動(account の接続待ちで channel の connect が遅延しないように)
586
  channel_thread = threading.Thread(
587
  target=channel_worker,
588
- args=(token_holder["token"], channel_id, manager_id, stop_event),
 
 
 
 
 
 
589
  name="channel-ws",
590
  daemon=True,
591
  )
 
25
  "?platform=web&EIO=4&transport=websocket"
26
  )
27
 
28
+ # heartbeat 応答を待つタイムアウト
29
+ HEARTBEAT_RESPONSE_TIMEOUT = 5.0
30
  TOKEN_CHECK_INTERVAL = 1.0
31
  REQUEST_TIMEOUT = 30.0
32
 
 
349
 
350
 
351
  def send_refresh(ws: LoggingWS, session_token: str) -> None:
352
+ """account WS 用の refresh(channelId は送らない)"""
353
  message = (
354
  '42/desk/account,0'
355
  + json.dumps(
 
362
  ws.send(message)
363
 
364
 
365
+ def send_channel_refresh(
366
+ ws: LoggingWS, session_token: str, channel_id: str
367
+ ) -> None:
368
+ """channel WS 用の refresh(channelId を含める)"""
369
+ message = (
370
+ '42/desk/channel,3'
371
+ + json.dumps(
372
+ ["refresh", {"jwt": session_token, "channelId": channel_id}],
373
+ ensure_ascii=False,
374
+ separators=(",", ":"),
375
+ )
376
+ )
377
+ log(
378
+ "SOCKET",
379
+ f"refresh を送信します(channel WS, channelId={channel_id})。",
380
+ )
381
+ ws.send(message)
382
+
383
+
384
  def send_heartbeat(ws: LoggingWS, manager_id: str) -> None:
385
  message = (
386
  '42/desk/channel,'
 
471
  channel_id: str,
472
  manager_id: str,
473
  stop_event: threading.Event,
474
+ token_holder: dict[str, str],
475
  ) -> None:
476
  try:
477
  ws = open_channel_ws(session_token, channel_id)
 
479
  log("CHANNEL", f"接続失敗: {exc!r}")
480
  return
481
 
482
+ current_token = session_token
483
+ last_token_check = time.monotonic()
484
+
485
+ # 最初の heartbeat を送信(以降は応答が来るたびに ping-pong で送り続ける)
486
+ send_heartbeat(ws, manager_id)
487
+ last_heartbeat_sent = time.monotonic()
488
+
489
  log("SOCKET", "Channel 待機中...")
490
  try:
491
  while not stop_event.is_set():
492
  now = time.monotonic()
493
+
494
+ # heartbeat 応答が 5 秒以内に来なければ再送する
495
+ if now - last_heartbeat_sent >= HEARTBEAT_RESPONSE_TIMEOUT:
496
+ log(
497
+ "SOCKET",
498
+ f"heartbeat 応答が {HEARTBEAT_RESPONSE_TIMEOUT}s 以内に"
499
+ "来ませんでした。再送します。",
500
+ )
501
  send_heartbeat(ws, manager_id)
502
+ last_heartbeat_sent = now
503
+
504
+ # x-account の変更チェック(channel refresh 用)
505
+ if now - last_token_check >= TOKEN_CHECK_INTERVAL:
506
+ new_token = token_holder.get("token")
507
+ if new_token and new_token != current_token:
508
+ log("AUTH", "x-account 変更検出 -> Channel refresh 送信")
509
+ send_channel_refresh(ws, new_token, channel_id)
510
+ current_token = new_token
511
+ last_token_check = now
512
 
513
  try:
514
  packet = ws.recv()
 
531
  if namespace == "/desk/channel" and payload:
532
  event_name = payload[0]
533
  log("SOCKET", f"event={event_name}")
534
+ if event_name == "heartbeat":
535
+ # 応答が返ってきたので、次の heartbeat を送信
536
+ send_heartbeat(ws, manager_id)
537
+ last_heartbeat_sent = time.monotonic()
538
+ elif event_name == "create":
539
  print_create_message(payload)
540
+ elif event_name == "expired":
541
+ log("CHANNEL", "expired を受信しました。接続を終了します。")
542
+ break
543
  except Exception as exc:
544
  log("CHANNEL", f"エラーで終了: {exc!r}")
545
  finally:
 
565
  if now - last_token_check >= TOKEN_CHECK_INTERVAL:
566
  current_tokens = client.get_tokens() or {}
567
  current_session_token = current_tokens.get("x-account")
568
+ if (
569
+ current_session_token
570
+ and current_session_token != token_holder["token"]
571
+ ):
572
  log("AUTH", "x-account 変更検出 -> refresh 送信")
573
  send_refresh(ws, current_session_token)
574
  token_holder["token"] = current_session_token
 
626
  tokens = client.get_tokens()
627
  if not tokens:
628
  raise RuntimeError("get_tokens() が空でした。")
629
+ required = (
630
+ "ch-session-1",
631
+ "ch-veil-id",
632
+ "x-account",
633
+ "x-account-refresh",
634
+ )
635
  missing = [k for k in required if not tokens.get(k)]
636
  if missing:
637
+ raise RuntimeError(
638
+ "必要なトークンが取得できません: " + ", ".join(missing)
639
+ )
640
 
641
  manager_id, channel_id = fetch_ids(tokens)
642
  token_holder = {"token": tokens["x-account"]}
643
 
644
  stop_event = threading.Event()
645
 
646
+ # channel 側を先に起動
647
  channel_thread = threading.Thread(
648
  target=channel_worker,
649
+ args=(
650
+ token_holder["token"],
651
+ channel_id,
652
+ manager_id,
653
+ stop_event,
654
+ token_holder,
655
+ ),
656
  name="channel-ws",
657
  daemon=True,
658
  )