2013-08-19 37 views
9

Tôi đang sử dụng Flask cùng với gevent-socketio:gevent-socketio không sử dụng @ tôi app.route endpoint cho socketio

$ cat requirements.txt 
Flask==0.10.1 
Jinja2==2.7.1 
MarkupSafe==0.18 
Werkzeug==0.9.3 
argparse==1.2.1 
gevent==0.13.8 
gevent-socketio==0.3.5-rc2 
gevent-websocket==0.3.6 
greenlet==0.4.1 
itsdangerous==0.23 
wsgiref==0.1.2 

Tôi đang sử dụng một thiết lập khá tiêu chuẩn để khởi động server:

#Called from __main__ 
def run_dev_server(): 
    app.debug = True 
    port = 5000 
    dapp = werkzeug.debug.DebuggedApplication(app, evalex = True) 
    SocketIOServer(('', port), dapp, resource="socket.io").serve_forever() 

Và một cái móc khá chuẩn cho namespace SocketIO tôi:

@app.route('/socket.io/<path:rest>') 
def push_stream(rest): 
    print 'ws connect', rest 
    try: 
     socketio.socketio_manage(request.environ, {'/join_notification': JoinsNamespace}, request) 
    except Exception as e: 
     app.logger.error("Exception while handling socketio connection", exc_info=True) 
    return flask.Response() 

Tuy nhiên, tôi đang gặp vấn đề ở đâu 'kết nối' thậm chí ts không bị sa thải trên máy khách. Sau một chút đào bới, tôi nhận ra rằng mặc dù tôi nhận được thông báo 127.0.0.1 - - [2013-08-19 12:53:57] "GET /socket.io/1/websocket/170191232666 HTTP/1.1" 101 - - ở đầu ra, tôi đã không nhận được thông báo ws connect (trong khi các lệnh in khác trong mã hoạt động tốt). Tôi nhận xét rằng điểm cuối, và chắc chắn nó thậm chí không được gọi. Điều đó sẽ giải thích tại sao không gian tên của tôi không được sử dụng. Nhưng tại sao? Tôi có đăng ký không gian tên của mình sai không?

print app.url_map sản lượng:

Map([<Rule '/' (HEAD, OPTIONS, GET) -> root>, 
<Rule '/socket.io/<rest>' (HEAD, OPTIONS, GET) -> push_stream>, 
<Rule '/static/<filename>' (HEAD, OPTIONS, GET) -> static>]) 

Vì vậy, không có gì khác thường.

Chỉnh sửa: Mã khách hàng:

socket = io.connect('/join_notification') 
console.log(socket) 

socket.on('connect', function() { 
    console.log('connected to websocket') 
    socket.emit('login', {'name': data['name']}) 
}) 

socket.on('disconnect', function() { 
    console.log('d/c\'d from websocket') 
}) 

socket.on('join_error', function() { 
    ... 
}) 

socket.on('join_success', function(data){ 
    ... 
}) 

socket.on('join', function(data) { 
    ... 
}) 
+0

Đăng mã khách hàng – leon

+0

Đã thêm mã máy khách. – Rotten194

+0

Nếu bạn đang nhận được /socket.io/1/ khi gọi kết nối, bạn đang làm điều gì đó sai. Kết nối nên được gọi với POST đến /socket.io/1/. Bằng cách bỏ phân đoạn tiếp theo, bạn đang khởi tạo một kết nối mới.Vì vậy, bạn đã kết nối và bạn đang nhận được phản hồi với "nội dung" ở cuối có nghĩa là nó hoạt động - hoặc bạn đang khởi tạo kết nối sai. Bây giờ, nếu nó hoạt động và nó không gọi mã CỦA BẠN, bạn có chắc là bạn đã khởi tạo không gian tên của mình một cách chính xác không? https://gevent-socketio.readthedocs.org/en/latest/namespace.html – blakev

Trả lời

1

Các hành vi kỳ lạ là vì dòng này:

dapp = werkzeug.debug.DebuggedApplication(app, evalex = True) 

Socketio và debugger Werkzeug không làm việc cùng nhau. Đã có sự cố mở về việc này, hãy xem: https://github.com/abourget/gevent-socketio/issues/114

Nhưng bạn có thể giải quyết vấn đề này bằng cách tạo lớp trình gỡ lỗi tùy chỉnh.

from werkzeug.debug import DebuggedApplication 
class MyDebuggedApplication(DebuggedApplication): 
    def __call__(self, environ, start_response): 
     # check if websocket call 
     if "wsgi.websocket" in environ and not environ["wsgi.websocket"] is None: 
      # a websocket call, no debugger ;) 
      return self.app(environ, start_response) 
     # else go on with debugger 
     return DebuggedApplication.__call__(self, environ, start_response) 

# remember to call the overwritten debugger in your run_dev_server() function 
dapp = MyDebuggedApplication(app, evalex = True) 

Bản vá dựa trên wsgi.websocket khóa môi trường, dường như chỉ xuất hiện trong cuộc gọi websocket. Hãy cẩn thận, tôi đã không suy nghĩ nhiều về điều đó, có thể có những vấn đề khác.

+0

Cảm ơn bạn! Tôi nghĩ rằng tôi đã thử điều đó, nhưng tôi đoán tôi đã làm điều đó sai bởi vì nó đã làm việc lần này. – Rotten194

1

Đã cho tôi một thời gian, nhưng có vẻ như tôi đã giải quyết nó, thưởng thức:

https://github.com/Aldanor/SocketIO-Flask-Debug

Tóm lại:

  • bạn cần phải giải nén một cách rõ ràng các giá trị từ các máy phát điện được trả về bởi werkzeug.debug.DebuggedỨng dụng bất cứ khi nào yêu cầu socket.io được phát hiện, điều này cho phép thiết lập kết nối ổ cắm đúng cách
  • trình xử lý vùng tên socket.io sẽ không được trình bày kzeug theo mặc định, vì vậy bạn cần chèn câu trả lời thử của riêng bạn, lưu truy nguyên nếu một ngoại lệ bị bắt và sau đó lấy lại nó ở đâu đó trong ngữ cảnh yêu cầu
+0

Đừng trả lời bằng liên kết. Giải thích cách giải quyết vấn đề ở đây. Đọc câu hỏi thường gặp để biết thêm thông tin. –

+0

Tôi chỉ muốn giúp đỡ người khác nếu có bất cứ điều gì (được cho là tôi đã đấu tranh với vấn đề này bao nhiêu). Liên kết ở trên chứa một ví dụ làm việc với mã được viết đầy đủ, có vấn đề gì với nó? Dù sao, cập nhật câu trả lời. – aldanor

Các vấn đề liên quan