class_docstr: Implements a custom Tornado WebSocketHandler for the Bokeh Server.
  
      
docstr: Initialize a connection to a client.
  
  Returns:
      None
docstr_tok: ["Initialize","a","connection","to","a","client",".","Returns",":","None"]
code: def open(self) -> None:
      """Initialize a connection to a client.
  
      Returns:
          None
  
      """
      log.info("WebSocket connection opened")
      token = self._token
  
      if self.selected_subprotocol != "bokeh":
          self.close()
          raise ProtocolError("Subprotocol header is not 'bokeh'")
      elif token is None:
          self.close()
          raise ProtocolError("No token received in subprotocol header")
  
      now = calendar.timegm(
          dt.datetime.now(tz=dt.timezone.utc).timetuple()
      )
      payload = get_token_payload(token)
      if "session_expiry" not in payload:
          self.close()
          raise ProtocolError("Session expiry has not been provided")
      elif now >= payload["session_expiry"]:
          self.close()
          raise ProtocolError("Token is expired.")
      elif not check_token_signature(
          token,
          signed=self.application.sign_sessions,
          secret_key=self.application.secret_key,
      ):
          session_id = get_session_id(token)
          log.error(
              "Token for session %r had invalid signature", session_id
          )
          raise ProtocolError("Invalid token signature")
  
      try:
          self.application.io_loop.add_callback(
              self._async_open, self._token
          )
      except Exception as e:
          # this isn't really an error (unless we have a
          # bug), it just means a client disconnected
          # immediately, most likely.
          log.debug("Failed to fully open connection %r", e)
  
imports: from __future__ import annotations
  import logging
  import calendar
  import datetime
  from typing import TYPE_CHECKING, Any, cast
  from urllib.parse import urlparse
  from tornado import locks, web
  from tornado.websocket import WebSocketClosedError, WebSocketHandler
  from bokeh.settings import settings
  from bokeh.util.token import check_token_signature, get_session_id, get_token_payload
  from ...protocol import Protocol
  from ...protocol.exceptions import MessageError, ProtocolError, ValidationError
  from ...protocol.message import Message
  from ...protocol.receiver import Receiver
  from ...util.dataclasses import dataclass
  from ..protocol_handler import ProtocolHandler
  from .auth_request_handler import AuthRequestHandler
label_desc: Use image node_id 4 for calling the WSHandler obj's underlying member method code with example usage: obj.open() without return types