为什么asyncio.sleep()阻止我的WebSocket服务器接收输入?

时间:2019-02-02 05:20:34

标签: python-3.x websocket sleep python-asyncio

我正在尝试构建一个库,该库允许对从属浏览器应用程序中的dom进行python控制。

目前我正在试图不发送信息到DOM,但请求,然后从它接收的一条信息。

下面的示例配置为获取有关给定元素的属性(在这种情况下为id)。

设置非常简单。发送请求,重复检查该请求的ID是否在注册表中注册为非值,使用asyncio.sleep暂停检查过程并将控制权释放回接收方,以便接收。

顺便说一句,这是(假设)工作实现的几乎相同的副本。搜索Python的索菲桂在谷歌,如果你很好奇。

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

变种插座= 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 :(得分:0)

没有设置requests[request_id],因此while循环将永远不会退出。另外,您应该避免使用全局变量。

答案 1 :(得分:0)

package com.entity;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;

@Entity
@Table(name="user")
public class User {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="user_id")
    private int userId;

    @Column(name="role")
    private String role;

    @OneToOne(cascade=CascadeType.ALL)
    @JoinColumn(name="user_personal_details_id")
    private UserPersonalDetails userPersonalDetails;

    public User() {

    }

    public User(String role) {
        this.role = role;
    }
    public String getRole() {
        return role;
    }

    public void setRole(String role) {
        this.role = role;
    }

    public UserPersonalDetails getUserPersonalDetails() {
        return userPersonalDetails;
    }

    public void setUserPersonalDetails(UserPersonalDetails userPersonalDetails) {
        this.userPersonalDetails = userPersonalDetails;
    }

    public int getUserId() {
        return userId;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }
    @Override
    public String toString() {
        return "User [userId=" + userId + ", role=" + role + ", userPersonalDetails=" + userPersonalDetails + "]";
    }
}

package com.repository.impl;

import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.transaction.annotation.Transactional;

import com.entity.Project;
import com.repository.ProjectRepository;

@Transactional
public class ProjectRepositoryImpl implements ProjectRepository {

    private SessionFactory sessionFactory;

    public ProjectRepositoryImpl(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }
    @Override
    public Project saveProject(Project project) {
        Session session = sessionFactory.getCurrentSession();
        session.saveOrUpdate(project);
        return project;
    }

    @Override
    public Project getProject(int projectId) {
        Session session = sessionFactory.getCurrentSession();
        Project project = session.get(Project.class, projectId);
        return project;
    }

    @Override
    public List<Project> getProjects() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public int deleteProject(int projectId) {
        Session session = sessionFactory.getCurrentSession();
        Project project = getProject(projectId);
        session.delete(project);
        return projectId;
    }
}

虽然解决了。

if message[ 'message' ] == 'response': receive_response( message ) 的while循环中,我放置了:

def receive_response( message ):

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

并创建函数:

receive_response

尽管我没有接受过正规教育,所以我问,你为什么对全球人士不满意?他们一直为我服务得很好。