瓶子 + WebSocket

Posted

技术标签:

【中文标题】瓶子 + WebSocket【英文标题】:Bottle + WebSocket 【发布时间】:2012-05-06 04:18:35 【问题描述】:

是否可以在同一个应用程序(相同端口)中托管一个普通的 Bottle 应用程序和一个 WebSocket 应用程序(例如:https://github.com/defnull/bottle/blob/master/docs/async.rst)? 这样 /ws 将转到 WebSocket 处理程序,而所有其他的将通常路由到其他瓶处理程序。

【问题讨论】:

【参考方案1】:

确实如此。

服务器:

#!/usr/bin/python

import json
from bottle import route, run, request, abort, Bottle ,static_file
from pymongo import Connection
from gevent import monkey; monkey.patch_all()
from time import sleep

app = Bottle()

@app.route('/websocket')
def handle_websocket():
    wsock = request.environ.get('wsgi.websocket')
    if not wsock:
        abort(400, 'Expected WebSocket request.')
    while True:
        try:
            message = wsock.receive()
            wsock.send("Your message was: %r" % message)
            sleep(3)
            wsock.send("Your message was: %r" % message)
        except WebSocketError:
            break

@app.route('/<filename:path>')
def send_html(filename):
    return static_file(filename, root='./static', mimetype='text/html')


from gevent.pywsgi import WSGIServer
from geventwebsocket import WebSocketHandler, WebSocketError

host = "127.0.0.1"
port = 8080

server = WSGIServer((host, port), app,
                    handler_class=WebSocketHandler)
print "access @ http://%s:%s/websocket.html" % (host,port)
server.serve_forever()

保存 javascript 的 html 页面:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <script type="text/javascript">
    var ws = new WebSocket("ws://localhost:8080/websocket");
    ws.onopen = function() 
        ws.send("Hello, world");
    ;
    ws.onmessage = function (evt) 
        alert(evt.data);
    ;
  </script>
</head>
<body>
</body>
</html>

一个客户:

#!/usr/bin/python

from websocket import create_connection
ws = create_connection("ws://localhost:8080/websocket")
print "Sending 'Hello, World'..."
ws.send("Hello, World")
print "Sent"
print "Reeiving..."
result =  ws.recv()
print "Received '%s'" % result
ws.close()

【讨论】:

通常瓶子应用程序是这样启动的:run(server='gevent', host='localhost', port=8192, debug=True, reloader=True) 这些参数现在会去哪里? @spacen-jasset run 也将其作为参数。喜欢:bottle.run(app=config.application, host='0.0.0.0', port=3001, reloader=True, server='gevent', handler_class=WebSocketHandler) 我尝试将上述内容添加到现有的瓶子应用程序中,确保我拥有所有导入、/websocket 路由以及from gevent.pywsgi import WSGIServer 下面的所有 Python 代码。使用的 Javascript 代码如图所示。我在virtualenv 中安装了pip geventgevent-websocket,但出现错误:from geventwebsocket import WebSocketHandler, WebSocketError [Tue Aug 23 14:20:10.425900 2016] [wsgi:error] [pid 7245:tid 139987894220544] [client 127.0.0.1:58218] ImportError: cannot import name WebSocketHandler @user1063287 use from geventwebsocket import WebSocketError from geventwebsocket.handler import WebSocketHandler 即使没有错误,答案也无法路由到“/”或任何其他非 websocket 路径。【参考方案2】:

这很可能不是最简单的答案,但我刚刚完成了一个测试环境的设置,该环境在 Pyramid 上使用 nginx 和 uWSGI,一旦你设置好了,你就可以非常轻松地扩展它,例如,如果你的/ws 占用了太多资源,使用 Nginx+uWSGI 将 /ws 重新定位到不同的硬件是微不足道的。我的背景是 Pyramid,我的 uWSGI 经验只是测试,但在我的阅读中,它似乎是一个应该很好用的解决方案。瓶子的说明是通过谷歌快速搜索的结果。

概念:

这个概念是在 app.serve_forever() 调用之前获取您的应用程序,即您的 app = make_wsgi_app.from_config(config) ,而是使用 uwsgi 来“服务”您的应用程序到一个套接字 app1.sock。有很多方法可以配置 uWSGI。 uWSGI 站点提供了更多配置 uWSGI 以与您的应用程序对话的方法的文档。 Nginx 带有配置,至少在当前版本中可以原生使用 uWSGI 套接字。您只需将 uwsgi_pass unix:///tmp/app1.sock; 路径与参数一起传递给站点配置。在同一个站点 conf 文件中执行此操作两次,一次用于 location / ,一次用于 location /ws 指向它们各自的应用程序 sock 文件,你应该很高兴.

当我设置测试环境时,将应用程序作为文件提供给套接字的概念对我来说是新的,我希望这会有所帮助。

获得什么:

nginx uWSGI

方法:

从this tutorial 中提取 nginx 和 uwsgi 设置信息并将其提供给您的应用程序,here 用于特定于瓶子的设置,或者前往 uwsgi 站点并查看它们的配置说明。每个特定技术的文档都非常好,因此即使缺乏组合示例,让它们一起工作也不难。 Nginx 和 uWSGI 都有大量的配置设置,所以一定要看看这些。

【讨论】:

以上是关于瓶子 + WebSocket的主要内容,如果未能解决你的问题,请参考以下文章

交换瓶子

交换瓶子_贪心

题解倒水

如何通过Matlab检测红色圆圈中不规则放置的瓶子,同时排除那些规则圆形瓶子?

D - 小Z的加油店

交换瓶子 --- 蓝桥杯 (暴力)