class_docstr: A WebSocket connection.
  
  Call :meth:`connect` before :meth:`send` and :meth:`receive`.
  
  All methods are thread safe.
  
  Parameters
  ----------
  url
      The WebSocket URL.
      For tuner command channel it should be something like ``ws://localhost:8080/tuner``.
class_docstr_tok: ["A","WebSocket","connection",".","Call",":","meth",":","`","connect","`","before",":","meth",":","`","send","`","and",":","meth",":","`","receive","`",".","All","methods","are","thread","safe",".","Parameters","--","--","--","--","--","url","The","WebSocket","URL",".","For","tuner","command","channel","it","should","be","something","like","``","ws",":","\/\/localhost:8080\/tuner","``","."]
docstr: Return received message;
  or return ``None`` if the connection has been closed by peer.
docstr_tok: ["Return","received","message",";","or","return","``","None","``","if","the","connection","has","been","closed","by","peer","."]
code: def receive(self) -> Command | None:
      """
      Return received message;
      or return ``None`` if the connection has been closed by peer.
      """
      try:
          msg = _wait(self._ws.recv())
          _logger.debug(f"Received {msg}")
      except websockets.ConnectionClosed:  # type: ignore
          _logger.debug("Connection closed by server.")
          self._ws = None
          _decrease_refcnt()
          raise
  
      if msg is None:
          return None
      # seems the library will inference whether it's text or binary, so we don't have guarantee
      if isinstance(msg, bytes):
          msg = msg.decode()
      return nni.load(msg)
  
file_path: nni/nni/runtime/command_channel/websocket/connection.py
imports: from __future__ import annotations
  import asyncio
  import logging
  from threading import Lock, Thread
  from typing import Any, Type
  import websockets
  import nni
  from ..base import Command
label_desc: Use image node_id 6 for calling the WsConnection obj's underlying member method code with example usage: obj.receive() and returns: nni, None