Почему asyncio.sleep () не позволяет моему серверу веб-сокетов получать входные данные? - PullRequest
0 голосов
/ 02 февраля 2019

Я пытаюсь создать библиотеку, которая позволяет Python контролировать dom в ведомом браузерном приложении.

В настоящее время я пытаюсь не отправлять информацию в dom, а запрашивать, а затем получать фрагментинформация из него.

Этот пример ниже сконфигурирован для реквизиции атрибута (в данном случае id) данного элемента.

Настройка довольно проста.Отправьте запрос, повторно проверяйте, чтобы идентификатор этого запроса был зарегистрирован как не-None значение в реестре, используя asyncio.sleep, чтобы остановить процедуру проверки и вернуть управление обратно получателю, чтобы он мог, ну, в общем, получать.

Это, кстати, почти идентичная копия (предположительно) работающей реализации.Если вам интересно, поищите Python Sofi Gui в google.

asyncio.sleep, кажется, останавливает весь процесс, а не возвращает управление веб-серверу для получения сигналов.Есть ли проблема с моим пониманием, моей реализацией или и тем и другим?

python

import os, sys, asyncio, websockets, json, time

websocket_global = None
requests = {}

event_loop = asyncio.get_event_loop()

def quit():

    os.system( 'kill $(lsof -t -i :9000)' )

async def load( websocket ):

    await get_attribute( websocket, 'head', 'id' )

async def receive( websocket, path ):

    try: 
        async for input in websocket: await handle_input( websocket, input )

    except Exception as e: os.system( 'kill $(lsof -t -i :9000)' )

async def handle_input( websocket, input ):

    message = json.loads( input )

    if message[ 'message' ] == 'quit': quit()

    if message[ 'message' ] == 'load': await load( websocket )

    if message[ 'message' ] == 'response': receive_response( message )

def transmit( websocket, message ):

    asyncio.run_coroutine_threadsafe( websocket.send( message ), event_loop )

def receive_response( message ):

    responses[ message[ 'message_id' ] ] = message[ 'value' ]

async def wait_for_response( request_id ):

    while requests[ request_id ] == None: await asyncio.sleep( .01 )

    print( requests[ request_id ] ) ###<------------- The above asyncio.sleep is blocking the rest of the progrem
                                ###preventing the receive function from firing. Isn't sleep supposed to
                                ###let the program continue?

 async def get_attribute( websocket, selector, attr ):

    request_id = time.time(); requests[ request_id ] = None

    transmit( websocket, json.dumps( { 'message': 'get_attribute', 'request_id': request_id, 'selector': selector, 'attr': attr } ) )

    response = await wait_for_response( request_id )

    return response

quit()

html_path = os.path.dirname( os.path.realpath( __file__ ) )
html_path = html_path.replace( ' ', '\ ' )
html_path = html_path + '/main.html'

os.system( 'open -a Safari ' + html_path )

start_server = websockets.serve( receive, '0.0.0.0', 9000 )
event_loop.run_until_complete( start_server )
event_loop.run_forever()

javascript

var socket = null;

function get_attribute( message ) {

    var response = {};
    var target_element = document.getElementById( message[ 'selector' ] );

    if ( target_element == null ) {
        response = { 'message': 'response', 'request_id': message[ 'request_id' ], 'response': 'Element not Found' };
    }

    if ( target_element != null && target_element.getAttribute( message[ 'attr' ] ) == null ) {
        response = { 'message': 'response', 'request_id': message[ 'request_id' ], 'response': 'Attribute not Found' };
    }

    if ( target_element != null && target_element.getAttribute( message[ 'attr' ] ) != null ) {
        var target_attribute = target_element.getAttribute( message[ 'attr' ] )
        response = { 'message': 'response', 'request_id': message[ 'request_id' ], 'response': target_attribute };
    }

    socket.send( JSON.stringify( response ) );

}

function handle_input( message ) {

    if ( message[ 'message' ] == 'get_attribute' ) { get_attribute( message ) }

}

window.onload = function(event) {

    socket = new WebSocket( 'ws://0.0.0.0:9000' );

    socket.onopen = function( event ) {
        socket.send( JSON.stringify( { 'message': 'load' } ) )
        setInterval( function () { socket.send( JSON.stringify( { 'message': 'tick' } ) ) }, 1000 )
    }

    socket.onmessage = function( event ) {
        handle_input( JSON.parse( event.data ) )
    }

}

window.onbeforeunload = function( event ) {
    socket.send( JSON.stringify( { 'message': 'quit' } ) )
}

html

<!DOCTYPE html>
<html>
<head id="head">
    <title>Test</title>
    <script type="text/javascript" src="handler.js"></script>
</head>
<body id="body">

</body>
</html>

Извиняюсь за плохие орфографические или синтаксические ошибки.Моя клавиатура начинает работать, и различные клавиши перестают работать.

Ответы [ 2 ]

0 голосов
/ 03 февраля 2019
if message[ 'message' ] == 'response': receive_response( message )

и

def receive_response( message ):

    responses[ message[ 'message_id' ] ] = message[ 'value' ]

Решено, хотя.

В цикле while в receive_response Я поместил:

message = await pyscript.websocket.recv();

handle_response( json.loads( message ) );

и создал функцию:

def handle_response( input ):

    if input[ 'message' ] == 'response': receive_response( input );

Хотя у меня нет формального образования, поэтому я спрашиваю, почему вы недовольны глобалами?Они всегда служили мне достаточно хорошо.

0 голосов
/ 03 февраля 2019

ничего не устанавливает requests[request_id], поэтому цикл while никогда не завершится.Также вам следует избегать глобальных переменных.

...