当前位置: 首页 > 面试题库 >

为什么gevent-websocket是同步的?

司马作人
2023-03-14
问题内容

我正在玩gevent和websockets。这是一个简单的回显服务器:

from gevent.pywsgi import WSGIServer
from geventwebsocket.handler import WebSocketHandler
from gevent import sleep
from datetime import datetime
def app(environ, start_response):
    ws = environ['wsgi.websocket']
    while True:
        data = ws.receive()
        print('{} got data "{}"'.format(
            datetime.now().strftime('%H:%M:%S'), data))
        sleep(5)
        ws.send(data)

server = WSGIServer(("", 10004), app,
    handler_class=WebSocketHandler)
server.serve_forever()

和客户:

<html>
    <body>
        <button type="button" id="push_data">Push</button>
    </body>
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.11.3.js"></script>
    <script>
        var ws = new WebSocket("ws://localhost:10004");
        ws.onmessage = function(evt) {
            console.log(evt)
        };
        $('#push_data').click(function(){
            console.log('sending data...');
            ws.send('sample data');
        });
    </script>
</html>

因为gevent我期望有几个Greenlet异步地为数据提供服务;也就是说,如果我几次将某些数据推送到websocket(快速单击“推送”按钮),那么我期望在等待5秒钟后将所有数据同时恢复。

但是,无论我单击“按钮”有多快,这都是我在控制台中看到的:

18:28:07 got data "sample data"
18:28:12 got data "sample data"
18:28:17 got data "sample data"
18:28:22 got data "sample data"
18:28:27 got data "sample data"

为什么它会同步接收我的数据,每5秒暂停一次?如何将其变成异步服务器?


问题答案:

该行为是同步的,因为您自己的代码是同步的。gevent只是使用事件循环的协程库。它不会神奇地将同步代码转换为异步代码。

请在以下位置查看文档:http :
//www.gevent.org/servers.html

据说服务器每个连接 (不是每个请求)生成一个greenlet 。因此,对同一连接的多个请求的执行将被序列化。

如果要同时处理同一连接的多个请求,则需要生成新的greenlet,或将处理委托给greenlet池。

这是一个示例(在每次请求时生成一个greenlet):

import gevent
from gevent.pywsgi import WSGIServer
from gevent.lock import Semaphore
from geventwebsocket.handler import WebSocketHandler
from datetime import datetime

def process(ws,data,sem):
    print('{} got data "{}"'.format(datetime.now().strftime('%H:%M:%S'), data))
    gevent.sleep(5)
    with sem:
        ws.send(data)

def app(environ, start_response):
    ws = environ['wsgi.websocket']
    sem = Semaphore()
    while True:
        data = ws.receive()
        gevent.spawn(process,ws,data,sem)

server = WSGIServer(("", 10004), app,handler_class=WebSocketHandler)
server.serve_forever()

注意信号灯的存在。因为处理是并发的,所以需要防止两个并发的greenlet同时在套接字上写入,从而导致消息损坏。

最后一点,使用此实现,不能保证将按照请求的顺序发送答复。



 类似资料:
  • 我刚刚发现,在react函数都是异步的,或者在调用它的函数完成后调用。 现在这两样东西很难消化 在博客中,函数是在函数内部调用的,但是触发函数的原因并不是被调用函数所知道的。 他们为什么要让异步,因为JS是单线程语言,而且这个setState不是WebAPI或服务器调用,所以只能在JS的线程上完成。他们这样做是为了使重新呈现不会停止所有事件侦听器和其他东西,还是有其他设计问题。

  • 问题内容: 这里的同步点是什么? 为什么不只是使用? 该代码段来自Android的BluetoothChat示例(在此处找到) 问题答案: 需要进行同步以确保您没有不一致的状态。 没有同步,代码将是: 现在,如果在执行方法调用之前将if语句检查和方法调用之间的连接从何处关闭,则可以将其分配为null。这将导致。

  • 问题内容: Prevayler保证所有写入(通过其事务)都是同步的。但是读呢? 如果不使用显式同步(在用户代码中),可以进行脏读吗? 如果将业务对象读取为: ? 如果是这样,哪种同步策略对用户代码有利? (考虑业务对象A包含业务对象Bs的集合), 使用同步集合(A中B的集合),例如从java.util.concurrent包中? 同步外部事务的集合读取与内部事务的集合写入,例如在读写之间使用“ s

  • 本文向大家介绍nodejs中require方法是同步还是异步操作?为什么?相关面试题,主要包含被问及nodejs中require方法是同步还是异步操作?为什么?时的应答技巧和注意事项,需要的朋友参考一下 同步 因为经常用到模块,并且一般都在模块顶端引入,所以把require做成同步,有助于代码整洁有序,增强可读性。 但是,I/O密集的地方尽量不要用require。所有的同步,都会阻塞Node,直到

  • 问题内容: 我已经开始学习线程同步。 同步方法: 同步块: 什么时候应该使用方法和块? 为什么块比方法更好? 问题答案: 这不是更好的问题,只是有所不同。 同步方法时,实际上是在与对象本身进行同步。对于静态方法,您正在同步到对象的类。因此,以下两段代码以相同的方式执行: 就像您写的一样。 如果要控制到特定对象的同步,或者只想将方法的 一部分 同步到该对象,则指定一个块。如果在方法声明上使用关键字,

  • wss:/www.mysite.ca/socket.io/?eio=3&transport=websocket 这就是chrome webdevoloper工具显示套接字IO的请求url的方式。 我试图了解更多关于eio=3&transport=websocket的信息。 我必须从API工具调用url

  • 互联网是超文本标记语言(HTML)页面的集合,它们彼此链接以形成概念性信息网络。随着时间的推移,静态资源数量增加,图像等更丰富的项目开始成为Web结构的一部分。 高级服务器技术允许动态服务器页面 - 其内容基于查询生成的页面。 很快,需要拥有更多动态网页才能获得动态超文本标记语言(DHTML)。一切都归功于JavaScript。在接下来的几年中,我们看到了跨帧通信,试图避免页面重新加载,然后在帧内

  • 本文向大家介绍react中的setState是同步还是异步的呢?为什么state并不一定会同步更新?相关面试题,主要包含被问及react中的setState是同步还是异步的呢?为什么state并不一定会同步更新?时的应答技巧和注意事项,需要的朋友参考一下 [react] react中的setState是同步还是异步的呢?为什么state并不一定会同步更新?