Tornado Websockets 演示不适用于 OpenShift

Tornado Websockets Demo not working on OpenShift

我正在尝试在 OpenShift 上获取 Tornado Websockets Demo 运行。我从 Python2.7 墨盒开始。

在 app.py 内,我绑定到 OpenShift 提供的 python 端口和 python IP 地址。代码部署没有任何问题,我可以转到我的站点并查看静态文件和索引。在我的客户端中,我确保连接到 OpenShift 标准 websocket 端口 (8000)。

但是,我无法发送或接收数据。每当我尝试发送消息时,我的浏览器控制台中都会出现以下错误:

WebSocket is already in CLOSING or CLOSED state.

我在下面包含了相关的代码部分:

app.py

import ...

ON_PAAS = 'OPENSHIFT_PYTHON_DIR' in os.environ

if ON_PAAS:
    port = int(os.environ['OPENSHIFT_PYTHON_PORT'])
    host = os.environ['OPENSHIFT_PYTHON_IP']
    debug = False
    dir_virtualenv = os.environ['OPENSHIFT_PYTHON_DIR'] + '/virtenv/'
    virtualenv = os.path.join(dir_virtualenv, 'bin/activate_this.py')
        try:
            execfile(virtualenv, dict(__file__=virtualenv))
        except IOError:
            pass
else:
    port = 8000
    host = '127.0.0.1'
    debug = True        

define("port", default=port, help="run on the given port", type=int)
define("host", default=host, help="run on the given host", type=str)
define("debug", default=debug, help="run in debug mode")

class Application(tornado.web.Application):
    def __init__(self):
        handlers = [
            (r"/", MainHandler),
            (r"/chatsocket", ChatSocketHandler),
        ]
        settings = dict(
            cookie_secret="__TODO:_GENERATE_YOUR_OWN_RANDOM_VALUE_HERE__",
            template_path=os.path.join(os.path.dirname(__file__), "templates"),
            static_path=os.path.join(os.path.dirname(__file__), "static"),
            xsrf_cookies=True,
        )
        tornado.web.Application.__init__(self, handlers, **settings)

class MainHandler(tornado.web.RequestHandler):
    ...

class ChatSocketHandler(tornado.websocket.WebSocketHandler):
    ...

def main():
    tornado.options.parse_command_line()
    app = Application()
    app.listen(options.port, address=options.host)
    tornado.ioloop.IOLoop.instance().start()

if __name__ == "__main__":
    main()

chat.js

...

var updater = {
    socket: null,

    start: function() {
        var url = "ws://" + location.host + ":8000/chatsocket";
        updater.socket = new WebSocket(url);
        updater.socket.onmessage = function(event) {
            updater.showMessage(JSON.parse(event.data));
        }
    },

    showMessage: function(message) {
        var existing = $("#m" + message.id);
        if (existing.length > 0) return;
        var node = $(message.html);
        node.hide();
        $("#inbox").append(node);
        node.slideDown();
    }
};

编辑:I assume that OpenShift supports WebSockets.虽然文档不是很详尽。

据我所知,OpenShift 仅允许端口 22 和 443 上的传入 TCP 连接。我认为您无法更改此设置。让您的 WebSocket 服务器也监听 443(而不是 8000)。这是很棒的事情:WebSocket 是对 HTTP 的升级——您的 Web 应用程序和您的 WebSocket 服务器可以 运行 在同一个端口上。您的 Web 服务器只需要被告知,正常的 HTTP 请求将被委托给您的 "normal" Web 应用程序,而 HTTP UPGRADE 请求将被委托给您的 WebSocket 服务器。

编辑:

我很难找到关于允许与 OpenShift 一起使用的端口的 官方 文档。从您提到的文章来看,您是对的,8000 和 8443 应该可以:

http://app-lovingwebsockets.rhcloud.com/  <= your current HTTP URL
http://app-lovingwebsockets.rhcloud.com:8000/ <= WebSockets enables HTTP URL

https://app-lovingwebsockets.rhcloud.com/  <= your current HTTPs URL
https://app-lovingwebsockets.rhcloud.com:8443/ <= WebSockets enables HTTPs URL

但是,这是一个 博客 post,不是官方文档,它是 2012 年的。从那以后可能发生了很多变化!您应该继续尝试查找有关在 OpenShift 上使用 WebSockets 的官方文档,真的。

您是否正确安装了 tornado.websocket.WebSocketHandler 派生实例作为 chatsocket 路由的处理程序?你没有在你的代码中显示这个。

我选择不使用 Tornado websocket 聊天演示来重新开始。我已经创建了一个 public github 存储库,其中包含允许功能性 websocket 的必要代码。

https://github.com/awwong1/django-tornado-websockets-openshift

我发现如果客户端和服务器运行在正常的 open shift 应用程序上,它就可以工作,如果客户端移动到我的 PC,我会遇到相同的行为,连接并突然收到与服务器的断开连接。但是不知道为什么。