它不完全是原始数据,其实现这一kepts连接打开,如果你检查wikipedia的文件,在握手请求正在创建连接时套接字HTTP协议的升级,有从客户端发送的信息流,以及来自服务器的答案。
所以一个WebSocket连接请求的一个示例将是
GET /mychat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat
Sec-WebSocket-Version: 13
Origin: http://example.com
其通过套接字发送作为字节流,但同样的事情发生与一个共同的http请求,不过,
如果您在上JS运行代码查看与轨道-的WebSocket创建的请求,
var dispatcher = new WebSocketRails('localhost:3000/websocket');
,你会看到,连接过来的请求网络是
GET /websocket HTTP/1.1
Host: localhost:3000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:19.0) Gecko/20100101 Firefox/19.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,es-ar;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Sec-WebSocket-Version: 13
Origin: http://localhost:3000
Sec-WebSocket-Key: dRpM9EesBFdk3SOH2QL/Tw==
Cookie: __utma=111872281.1938357651.1354053248.1355759500.1357797379.3; __utmz=111872281.1354053248.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); hblid=T1PaqE0vcRC9zDYrpFoBo5RD91766581; olfsk=olfsk5917359536568161; remember_admin_user_token=BAhbB1sGaQlJIiIkMmEkMTAkV0VhZzJaeXg3SzZFQWMzVUdPLktaTwY6BkVU--f84238cbbcb767e075117603de67f56a7150eb97; _stack_session=BAh7CEkiD3Nlc3Npb25faWQGOgZFRkkiJTg0NGIwNzZmNWUyZjFiNTMwZDkwMWUyMGFiODMxOGE3BjsAVEkiEF9jc3JmX3Rva2VuBjsARkkiMWxIS1FHUjg1b2pDbjFybFY4RW8yemtzRWtVQUdHY1BxTGxtdzBWOFdBN009BjsARkkiE3VzZXJfcmV0dXJuX3RvBjsARiIZL2hvbWUvcHJpdmF0ZV9hY3Rpb24%3D--e4823c74756cf70af0675323fb752b1f87064f09
Connection: keep-alive, Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
这样cookies被发送,以及最重要的,你的AuthorizationController:
class AuthorizationController < WebsocketRails::BaseController
def authorize_channels
# The channel name will be passed inside the message Hash
channel = Channel.find_by_name message[:channel]
if can?(:subscribe, channel)
accept_channel current_user
else
deny_channel({:message => 'authorization failed!'})
end
end
end
如果你把一个断点在authorize_channels方法,你会看到,你把所有的就好像它是一个普通的http请求一样。
有关WebSocket的工作原理和方式的更多信息,您可以阅读RFC,但重要的是,在创建连接时的握手过程中,客户端会将Cookie与其他信息一起发送某种类型的http请求,服务器接收到websocket请求,通过检查cookie来验证用户身份,并且打开连接保持打开状态作为全双工通信的套接字,或关闭连接,因为凭证无效。
我不知道我是否理解你的问题。一个普通的页面请求和一个web套接字的主要区别在于,一个web套接字是一个套接字,用户使用http握手来启动连接。
在您的代码上,这些行将HTTP请求与cookie一起发送,并且服务器接受连接。
// connect to server like normal
var dispatcher = new WebSocketRails('localhost:3000/websocket');
所以在这一点上,你有一个全双工套接字(这意味着,无论是服务器还是客户端可以在不超过冲突发送数据)。任何任意数据。
然后在下面的代码
:
// subscribe to the channel
var private_channel = dispatcher.subscribe_private('channel_name');
客户端是要求服务器(在还活着,在网页套接字连接)订阅的频道是私有的。
现在,需要了解的最重要的事情是,如果您订阅了一个频道,但您不打开新的连接,您仍然会使用相同的WebSocket,现在您要求订阅私人频道,并且这是您在开始连接时发送Cookie的websocket。
现在,如果碰巧你可以在websocket-rails gem上设置一个断点,在方法route(event)上没有文件dispatcher.rb,你会注意到在引擎盖下,websocket-rails使用faye-websocket -ruby来处理websocket连接,并且在请求中,你可以访问通过websocket握手发送的cookie。
的路由将请求路由到WebSocket的护栏控制器AuthorizationController,在大多数情况下,它具有类似于代码:
if can?(:subscribe, message[:channel])
accept_channel current_user
else
deny_channel({:message => 'authorization failed!'})
end
因为它可以访问辅助方法相同的公共轨道控制器,cancan?方法来自cancan,将调用current_user助手,并且此方法将具有完全访问cookie的权限。
因此,通道不是在websocket RFC上描述的,websocket只是一个可以用来发送任何数据的套接字,在这种情况下,公共和私有通道只是一种通信行为,由gem websocket-rails的作者创建了通信和广播消息给不同客户的渠道。
如果你进入的WebSocket护栏的问题,你会发现,甚至有请求创建单向担保渠道:https://github.com/DanKnox/websocket-rails/issues/52
因此,它不喜欢的人可以发送subscribe_to_private频道的流并访问在它们甚至可以发送流以进行订阅之前,它们必须通过http请求创建websocket连接,如rfc所述,然后,通过该websocket连接,它们必须发送字节流,询问ruby gem订阅该频道,当他们这样做时,在Rails服务器上,您可以自动访问连接创建时发送的WebSocket的Cookie。
查看https://developer.mozilla.org/en-US/docs/WebSockets/Writing_WebSocket_client_applications,看起来gem作者期望的行为不可靠或通用。 – bdares 2013-02-26 06:56:49
@bdares你是什么意思? – MhdSyrwan 2013-03-26 22:00:16