I'm trying to create a WS connection with my tornado server. The server code is simple:
我正在尝试与tornado服务器创建一个WS连接。服务器代码很简单:
class WebSocketHandler(tornado.websocket.WebSocketHandler):
def open(self):
print("WebSocket opened")
def on_message(self, message):
self.write_message(u"You said: " + message)
def on_close(self):
print("WebSocket closed")
def main():
settings = {
"static_path": os.path.join(os.path.dirname(__file__), "static")
}
app = tornado.web.Application([
(r'/ws', WebSocketHandler),
(r"/()$", tornado.web.StaticFileHandler, {'path':'static/index.html'}),
], **settings)
app.listen(8888)
tornado.ioloop.IOLoop.current().start()
I copy pasted the client code from here:
我从这里复制粘贴客户代码:
$(document).ready(function () {
if ("WebSocket" in window) {
console.log('WebSocket is supported by your browser.');
var serviceUrl = 'ws://localhost:8888/ws';
var protocol = 'Chat-1.0';
var socket = new WebSocket(serviceUrl, protocol);
socket.onopen = function () {
console.log('Connection Established!');
};
socket.onclose = function () {
console.log('Connection Closed!');
};
socket.onerror = function (error) {
console.log('Error Occured: ' + error);
};
socket.onmessage = function (e) {
if (typeof e.data === "string") {
console.log('String message received: ' + e.data);
}
else if (e.data instanceof ArrayBuffer) {
console.log('ArrayBuffer received: ' + e.data);
}
else if (e.data instanceof Blob) {
console.log('Blob received: ' + e.data);
}
};
socket.send("Hello WebSocket!");
socket.close();
}
});
When it tries to connect i get the following output on the browser's console:
当它试图连接时,我在浏览器的控制台得到如下输出:
WebSocket connection to 'ws://localhost:8888/ws' failed: Error during WebSocket handshake: Sent non-empty 'Sec-WebSocket-Protocol' header but no response was received
Why is that?
这是为什么呢?
1 个解决方案
#1
17
As pointed out in whatwg.org's Websocket documentation (it's a copy from the standard's draft):
正如whatwg.org的Websocket文档所指出的(它是标准草案的副本):
The WebSocket(url, protocols) constructor takes one or two arguments. The first argument, url, specifies the URL to which to connect. The second, protocols, if present, is either a string or an array of strings. If it is a string, it is equivalent to an array consisting of just that string; if it is omitted, it is equivalent to the empty array. Each string in the array is a subprotocol name. The connection will only be established if the server reports that it has selected one of these subprotocols. The subprotocol names must all be strings that match the requirements for elements that comprise the value of Sec-WebSocket-Protocol fields as defined by the WebSocket protocol specification.
WebSocket(url,协议)构造函数接受一个或两个参数。第一个参数url指定要连接的url。第二,协议,如果存在,则是字符串或字符串数组。如果它是一个字符串,它等价于由这个字符串组成的数组;如果省略它,它等价于空数组。数组中的每个字符串都是子协议名。只有当服务器报告它已经选择了其中一个子协议时,才会建立连接。子协议名称必须都是字符串,这些字符串必须符合由WebSocket协议规范定义的secl -WebSocket协议字段值组成的元素的要求。
Your server answers the websocket connection request with an empty Sec-WebSocket-Protocol header, since it doesn't support the Chat-1 subprotocol.
您的服务器使用一个空的secl - websocket - protocol头来响应websocket连接请求,因为它不支持Chat-1子协议。
Since you're writing both the server side and the client side (and unless your writing an API you intend to share), it shouldn't be super important to set a specific subprotocol name.
既然您同时编写了服务器端和客户端(除非您编写了一个您想要共享的API),那么设置一个特定的子协议名称就不太重要了。
You can fix this by either removing the subprotocol name from the javascript connection:
您可以通过从javascript连接中删除子协议名称来解决这个问题:
var socket = new WebSocket(serviceUrl);
Or by modifying your server to support the protocol requested.
或者修改服务器以支持请求的协议。
I could give a Ruby example, but I can't give a Python example since I don't have enough information.
我可以举一个Ruby的例子,但是我不能给出一个Python示例,因为我没有足够的信息。