2016-03-04 47 views
1

我對龍捲風框架比較陌生,迄今爲止,事情一直很混亂,特別是在處理web套接字時。到目前爲止,我的代碼如下所示:帶龍捲風的Websockets

import tornado.options 
import tornado.web 
import tornado.websocket 
import tornado.ioloop 

from tornado.options import options, define 

define(name='port', default=8000, help='.', type=int) 

class WSHandler(tornado.websocket.WebSocketHandler): 
    clients = [] 

    def open(self): 
     WSHandler.clients.append(self) 
     self.write('client connected') 

    def on_close(self): 
     WSHandler.clients.remove(self) 
     self.write('client removed') 

    def on_message(self, message): 
     for client in WSHandler.clients: 
      WSHandler.client.write_message(message) 

    def check_origin(self, origin): 
     return True 

if __name__ == '__main__': 
    tornado.options.parse_command_line() 
    application = tornado.web.Application(
     handlers=[ 
      (r'/webSocket', WSHandler), 
     ], 
    ) 
    application.listen(options.port) 
    tornado.ioloop.IOLoop.instance().start() 

和JavaScript文件看起來像這樣

var ws = new WebSocket("ws://localhost:8000/webSocket") 
 
ws.onopen = function() { 
 
    ws.setData('Hello World'); 
 
}; 
 
ws.onmessage = function(evt) { 
 
    ws.send(evt.data); 
 
};

我目前正在讀的書「介紹龍捲風」,並意識到,有些事情是現已棄用。我確實下載了git-hub上提供的演示,並嘗試瞭解websocket演示。

我試圖創建一個簡單的WebSocket應用程序,但它的作用是給我這個錯誤:

Can "Upgrade" only to "WebSocket"

另外,我有龍捲風
另一個問題是什麼_()是什麼意思?在文檔中給出的示例是

_("A person liked this", "%(num)d people liked this", len(people)) % {"num": len(people)}

並且這應該返回「一個人喜歡這個」,如果只有一個人在人。我不太明白這是如何工作

我道歉,如果我犯了一個錯誤,就是愚蠢明顯

+0

我們面臨着類似的問題,因爲我們是從代理服務器後面的網絡測試。該代理正在刪除標題「連接:升級」。看到這個[答案](https://stackoverflow.com/a/23522393/1761793) – Ajoy

回答

2

我想你可以看到tornado source,你可以找到以下內容:

# Upgrade header should be present and should be equal to WebSocket 
    if self.request.headers.get("Upgrade", "").lower() != 'websocket': 
     self.set_status(400) 
     log_msg = "Can \"Upgrade\" only to \"WebSocket\"." 
     self.finish(log_msg) 
     gen_log.debug(log_msg) 
     return 

顯然, HTML5 WebSocket協議是一種新協議。它實現了瀏覽器和服務器的全雙工通信(全雙工)。但是使用http只能使單個通信。所以我建議你嘗試另一個演示。

服務器:

#!/usr/bin/python 
#coding:utf-8 
import os.path 

import tornado.httpserver 
import tornado.web 
import tornado.ioloop 
import tornado.options 
import tornado.httpclient 
import tornado.websocket 

import json 
class IndexHandler(tornado.web.RequestHandler): 
    def get(self): 
    self.render("index.html") 

class SocketHandler(tornado.websocket.WebSocketHandler): 
    """docstring for SocketHandler""" 
    clients = set() 

    @staticmethod 
    def send_to_all(message): 
     for c in SocketHandler.clients: 
      c.write_message(json.dumps(message)) 

    def open(self): 
     self.write_message(json.dumps({ 
      'type': 'sys', 
      'message': 'Welcome to WebSocket', 
     })) 
     SocketHandler.send_to_all({ 
      'type': 'sys', 
      'message': str(id(self)) + ' has joined', 
     }) 
     SocketHandler.clients.add(self) 

    def on_close(self): 
     SocketHandler.clients.remove(self) 
     SocketHandler.send_to_all({ 
      'type': 'sys', 
      'message': str(id(self)) + ' has left', 
     }) 

    def on_message(self, message): 
    SocketHandler.send_to_all({ 
    'type': 'user', 
    'id': id(self), 
    'message': message, 
     }) 

##MAIN 
if __name__ == '__main__': 
    app = tornado.web.Application(
    handlers=[ 
     (r"/", IndexHandler), 
     (r"/chat", SocketHandler) 
    ], 
    debug = True, 
    template_path = os.path.join(os.path.dirname(__file__), "templates"), 
     static_path = os.path.join(os.path.dirname(__file__), "static") 
) 
    app.listen(8000) 
    tornado.ioloop.IOLoop.instance().start() 

客戶:

<html> 
<head> 
<script type="text/javascript"> 
var ws = new WebSocket("ws://localhost:8000/chat"); 
ws.onmessage = function(event) { 
    console.log(event); 
} 
function send() { 
    ws.send(document.getElementById('chat').value); 
} 
</script> 
</head> 

<body> 
    <div> 
    hello 
    <input id="chat"> 
    <button onclick="send()">send</button> 
    </div>  
</body> 
</html>