EDIT:実際にアップグレードヘッダーが作成されたことがわかりました。Rails 5 ActionCableがステータス101のアップグレードヘッダーを返さないアップグレードの応答
私はaction-cable-exampleコードベースからWebSocketアプリケーションを構築しようとしています。アプリで提供されているブラウザクライアントに依存する "Chatty"アプリケーションは正常に動作します。しかし、私は外部IoT接続が必要なので、そのクライアントを使用するつもりはありません。その結果、私は外部のブラウザ以外のデバイスとroute.rbで私の接続にWS/WSSのWebSocketプロトコルを実装しようとしていることである:
mount ActionCable.server => '/cable'
私は、このようなクロームシンプルなど、いくつかの外部クライアントを、試しましたWebSocket Clientの拡張機能とgem websocket-client-simpleでは、sample/client.rbを使用しています。どちらの場合も、ActionCableはアップグレードヘッダーを返しません。次のようにクロム拡張が文句を言う:
WebSocket connection to 'ws://127.0.0.1:3000/cable' failed: Error during WebSocket handshake: 'Upgrade' header is missing
にように、実際のハンドシェイクが、真であるとことを示しています
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat
:標準パー
**General**
Request URL:ws://127.0.0.1:3000/cable
Request Method:GET
Status Code:101 Switching Protocols
**Response Headers**
view source
Connection:keep-alive
Server:thin
**Request Headers**
view source
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Cache-Control:no-cache
Connection:Upgrade
Cookie:PPA_ID=<redacted>
DNT:1
Host:127.0.0.1:3000
Origin:chrome-extension://pfdhoblngboilpfeibdedpjgfnlcodoo
Pragma:no-cache
Sec-WebSocket-Extensions:permessage-deflate; client_max_window_bits
Sec-WebSocket-Key:1vokmzewcWf9e2RwMth0Lw==
Sec-WebSocket-Version:13
Upgrade:websocket
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.84 Safari/537.36
、レスポンスヘッダは、このようにしています
Sec-WebSocket-Acceptは、要求ヘッダーのSec-WebSocket-Keyに基づいて計算されるため、ws/wssが理解されていること、およびスイッチングプロトコルにはo ccur。
Started GET "/cable" for 127.0.0.1 at 2016-06-16 19:19:17 -0400
ActiveRecord::SchemaMigration Load (1.0ms) SELECT "schema_migrations".* FROM "schema_migrations"
Started GET "/cable/" [WebSocket] for 127.0.0.1 at 2016-06-16 19:19:17 -0400
Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
Finished "/cable/" [WebSocket] for 127.0.0.1 at 2016-06-16 19:19:18 -0400
はのWebSocketクライアント - シンプルで見ると、私はのWebSocketはclient.rbに戻っ決裂:クライアントが刻まとの接続を閉じますまで、このすべての中に
は、サーバーは、より幸せですまた、空のヘッダーも表示されました。コードを表示してからWebSocketを表示しています:
url = ARGV.shift || 'ws://localhost:3000/cable'
ws = WebSocket::Client::Simple.connect url
#<WebSocket::Client::Simple::Client:0x2cdaf68
@url="ws://localhost:3000/cable",
@socket=#<TCPSocket:fd 3>,
@handshake=<WebSocket::Handshake::Client:0x013231c8
@url="ws://localhost:3000/cable",
@headers={},
@state=:new,
@handler=#<WebSocket::Handshake::Handler::Client11:0x2e88400
@handshake=<WebSocket::Handshake::Client:0x013231c8
@url="ws://localhost:3000/cable",
@headers={},
@state=:new,
@handler=#<WebSocket::Handshake::Handler::Client11:0x2e88400 ...>,
@data="",
@secure=false,
@host="localhost",
@port=3000,
@path="/cable",
@query=nil,
@version=13>,
@key="KUJ0/C0rvoCMruW8STp0Sw==">,
@data="",
@secure=false,
@host="localhost",
@port=3000,
@path="/cable",
@query=nil,
@version=13>,
@handshaked=false,
@pipe_broken=false,
@closed=false,
@__events=[{:type=>:__close, :listener=>#<Proc:[email protected]:/Bitnami/rubystack-2.2.5-3/projects/websocket-client-simple/lib/websocket-client-simple/client.rb:37>, :params=>{:once=>true}, :id=>0}],
@thread=#<Thread:[email protected]:/Bitnami/rubystack-2.2.5-3/projects/websocket-client-simple/lib/websocket-client-simple/client.rb:42 sleep>
>;
この応答では、インスタンス変数 "@handshaked"がfalseとして返されました。これは関連しているかもしれませんが、私はこれまでにコード内でどこが設定されているか参照されていません。
更新: WebSocket :: Driver.startが実際にアップグレードヘッダーを作成していることが判明しました。そして、@ socket.write(レスポンス)はでEventMachineを通して送信します。 コード:
def start
return false unless @ready_state == 0
response = handshake_response
return false unless response
@socket.write(response)
open unless @stage == -1
true
end
handshake_responseは次のとおりです。
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: iJVnsG1ApNMFzABXGDSHN1V0i/s=