找回密码
 立即注册
搜索
热搜: 丝袜 魅魔 黑丝
查看: 8|回复: 0

14703368_【腐向】路人系列01

[复制链接]

13万

主题

343

回帖

22万

积分

管理员

站长

UID
1
积分
224402
余额
13 R
Moe币
84883
在线时间
279 小时
注册时间
2025-12-28
最后登录
2026-11-13
发表于 2026-9-3 23:00:59 | 显示全部楼层 |阅读模式
     See :func:`~trio.open_tcp_listeners` for details.
        host: Network interfaces the server binds to.
            See :func:`~trio.open_tcp_listeners` for details.
        backlog: Listen backlog. See :func:`~trio.open_tcp_listeners` for
            details.
        listeners: Preexisting TCP listeners. ``listeners`` replaces ``port``,
            ``host``, and ``backlog``. See :func:`trio.serve_listeners` for
            details.
        ssl: Configuration for enabling TLS on the connection.
        origins: Acceptable values of the ``Origin`` header, for defending
            against Cross-Site WebSocket Hijacking attacks. Values can be
            :class:`str` to test for an exact match or regular expressions
            compiled by :func:`re.compile` to test against a pattern. Include
            :obj:`None` in the list if the lack of an origin is acceptable.
        extensions: List of supported extensions, in order in which they
            should be negotiated and run.
        subprotocols: List of supported subprotocols, in order of decreasing
            preference.
        select_subprotocol: Callback for selecting a subprotocol among
            those supported by the client and the server. It receives a
            :class:`ServerConnection` (not a
            :class:`~websockets.server.ServerProtocol`!) instance and a list of
            subprotocols offered by the client. Other than the first argument,
            it has the same behavior as the
            :meth:`ServerProtocol.select_subprotocol
            <websockets.server.ServerProtocol.select_subprotocol>` method.
        compression: The "permessage-deflate" extension is enabled by default.
            Set ``compression`` to :obj:`None` to disable it. See the
            :doc:`compression guide <../../topics/compression>` for details.
        process_request: Intercept the request during the opening handshake.
            Return an HTTP response to force the response or :obj:`None` to
            continue normally. When you force an HTTP 101 Continue response, the
            handshake is successful. Else, the connection is aborted.
            ``process_request`` may be a function or a coroutine.
        process_response: Intercept the response during the opening handshake.
            Return an HTTP response to force the response or :obj:`None` to
            continue normally. When you force an HTTP 101 Continue response, the
            handshake is successful. Else, the connection is aborted.
            ``process_response`` may be a function or a coroutine.
        server_header: Value of  the ``Server`` response header.
            It defaults to ``"Python/x.y.z websockets/X.Y"``. Setting it to
            :obj:`None` removes the header.
        open_timeout: Timeout for opening connections in seconds.
            :obj:`None` disables the timeout.
        ping_interval: Interval between keepalive pings in seconds.
            :obj:`None` disables keepalive.
        ping_timeout: Timeout for keepalive pings in seconds.
            :obj:`None` disables timeouts.
        close_timeout: Timeout for closing connections in seconds.
            :obj:`None` disables the timeout.
        max_size: Maximum size of incoming messages in bytes.
            :obj:`None` disables the limit. You may pass a ``(max_message_size,
            max_fragment_size)`` tuple to set different limits for messages and
            fragments when you expect long messages sent in short fragments.
        max_queue: High-water mark of the buffer where frames are received.
            It defaults to 16 frames. The low-water mark defaults to ``max_queue
            // 4``. You may pass a ``(high, low)`` tuple to set the high-water
            and low-water marks. If you want to disable flow control entirely,
            you may set it to ``None``, although that's a bad idea.
        logger: Logger for this server.
            It defaults to ``logging.getLogger("websockets.server")``.
            See the :doc:`logging guide <../../topics/logging>` for details.
        create_connection: Factory for the :class:`ServerConnection` managing
            the connection. Set it to a wrapper or a subclass to customize
            connection handling.
        task_status: For compatibility with :meth:`nursery.start
            <trio.Nursery.start>`.

    """

    # Process parameters

    if subprotocols is not None:
        validate_subprotocols(subprotocols)

    if compression == "deflate":
        extensions = enable_server_permessage_deflate(extensions)
    elif compression is not None:
        raise ValueError(f"unsupported compression: {compression}")

    if create_connection is None:
        create_connection = ServerConnection

    # Create listeners

    if listeners is None:
        if port is None:
            raise ValueError("port is required when listeners is not provided")
        listeners = await trio.open_tcp_listeners(port, host=host, backlog=backlog)
    else:
        if port is not None:
            raise ValueError("port is incompatible with listeners")
        if host is not None:
            raise ValueError("host is incompatible with listeners")
        if backlog is not None:
            raise ValueError("backlog is incompatible with listeners")

    async def stream_handler(stream: trio.abc.Stream) -> None:
        """
        Handle the lifecycle of a WebSocket connection.

        Since this coroutine doesn't have a caller that can handle
        exceptions, it attempts to log relevant ones.

        It guarantees that the TCP connection is closed before exiting.

        """
        async with trio.open_nursery() as nursery:
            try:
                # Apply open_timeout to the TLS and WebSocket handshake.
                with (
                    trio.CancelScope()
                    if open_timeout is None
                    else trio.fail_after(open_timeout)
                ):
                    # Enable TLS.
                    if ssl is not None:
                        # Wrap with SSLStream here rather than with TLSListener
                        # in order to include the TLS handshake within open_timeout.
                        stream = trio.SSLStream(
                            stream,
                            ssl,
                            server_side=True,
                            https_compatible=True,
                        )
                        assert isinstance(stream, trio.SSLStream)  # help mypy
                        try:
                            await stream.do_handshake()
                        except trio.BrokenResourceError:
                            return

                    # Create a closure to give select_subprotocol access to connection.
                    protocol_select_subprotocol: (
                        Callable[
                            [ServerProtocol, Sequence[Subprotocol]],
                            Subprotocol | None,
                        ]
                        | None
                    ) = None
                    if select_subprotocol is not None:

                        def protocol_select_subprotocol(
                            protocol: ServerProtocol,
                            subprotocols: Sequence[Subprotocol],
                        ) -> Subprotocol | None:
                            # mypy doesn't know that select_subprotocol is immutable.
                            assert select_subprotocol is not None
                            # Ensure this function is only used in the intended context.
                            assert protocol is connection.protocol
                            return select_subprotocol(connection, subprotocols)

                    # Initialize WebSocket protocol.
                    protocol = ServerProtocol(
                        origins=origins,
                        extensions=extensions,
                        subprotocols=subprotocols,
                        select_subprotocol=protocol_select_subprotocol,
                        max_size=max_size,
                        logger=logger,
                    )

                    # Initialize WebSocket connection.
                    connection = create_connection(
                        nursery,
                        stream,
                        protocol,
                        server,
                        ping_interval=ping_interval,
                        ping_timeout=ping_timeout,
                        close_timeout=close_timeout,
                        max_queue=max_queue,
                    )

                    await connection.handshake(
                        process_request,
                        process_response,
                        server_header,
                    )

                if connection.protocol.state is not OPEN:
                    await connection.close_stream()
                    return

                server.all_connections.add(connection)
                connection.start_keepalive()
                try:
                    await handler(connection)
                except Exception:
                    connection.logger.error("connection handler failed", exc_info=True)
                    await connection.aclose(CloseCode.INTERNAL_ERROR)
                else:
                    await connection.aclose()
                finally:
                    server.all_connections.discard(connection)

            except Exception:
                # Don't leak connections when the opening handshake times out or
                # an unexpected error occurs.
                await trio.aclose_forcefully(stream)

    # The server variable is captured by the closure of conn_handler().
    server = Server(listeners, stream_handler, logger)
    await server.serve_forever(task_status=task_status)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|M男之家

GMT+8, 2026-11-14 05:37 , Processed in 0.042153 second(s), 22 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表