Spaces:
Running
Running
Update get_msg.py
Browse files- 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 |
-
|
|
|
|
| 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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 461 |
log("SOCKET", "Channel 待機中...")
|
| 462 |
try:
|
| 463 |
while not stop_event.is_set():
|
| 464 |
now = time.monotonic()
|
| 465 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 466 |
send_heartbeat(ws, manager_id)
|
| 467 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 == "
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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
|
|
|
|
|
|
|
|
|
|
| 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 = (
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 576 |
missing = [k for k in required if not tokens.get(k)]
|
| 577 |
if missing:
|
| 578 |
-
raise RuntimeError(
|
|
|
|
|
|
|
| 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 側を先に起動
|
| 586 |
channel_thread = threading.Thread(
|
| 587 |
target=channel_worker,
|
| 588 |
-
args=(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
)
|