Posted on

Error: probe transport websocket failed

參考文章

Socket.io 1.x: use WebSockets only?

相關參數

這個問題主要可參考Engine.io介紹的連線設定的章節

engine.io在建立連線時可以傳入下面的參數

  • pingTimeout (Number): how many ms without a pong packet to
    consider the connection closed (5000)
  • pingInterval (Number): how many ms before sending a new ping
    packet (25000)
  • upgradeTimeout (Number): how many ms before an uncompleted transport upgrade is cancelled (10000)
  • maxHttpBufferSize (Number): how many bytes or characters a message
    can be, before closing the session (to avoid DoS). Default
    value is 10E7.
  • allowRequest (Function): A function that receives a given handshake
    or upgrade request as its first parameter, and can decide whether to
    continue or not. The second argument is a function that needs to be
    called with the decided information: fn(err, success), where
    success is a boolean value where false means that the request is
    rejected, and err is an error code.
  • transports (<Array> String): transports to allow connections
    to (['polling', 'websocket'])
  • allowUpgrades (Boolean): whether to allow transport upgrades
    (true)
  • perMessageDeflate (Object|Boolean): parameters of the WebSocket permessage-deflate extension
    (see ws module api docs). Set to false to disable. (true)

    • threshold (Number): data is compressed only if the byte size is above this value (1024)
  • httpCompression (Object|Boolean): parameters of the http compression for the polling transports
    (see zlib api docs). Set to false to disable. (true)

    • threshold (Number): data is compressed only if the byte size is above this value (1024)
  • cookie (Object|Boolean): configuration of the cookie that
    contains the client sid to send as part of handshake response
    headers. This cookie might be used for sticky-session. Defaults to not sending any cookie (false).
    See here for all supported options.
  • wsEngine (String): what WebSocket server implementation to use. Specified module must conform to the ws interface (see ws module api docs). Default value is ws. An alternative c++ addon is also available by installing uws module.
  • cors (Object): the options that will be forwarded to the cors module. See there for all available options. Defaults to no CORS allowed.
  • initialPacket (Object): an optional packet which will be concatenated to the handshake packet emitted by Engine.IO.

其中和這篇文章的討論有關的是:transports
這個討論裡解答如下:

但其實這樣設定之後,其行為會不相同,原本是先用輪詢的方式握手,之後才開啟websocket,若是只設定websocket時,則若client端瀏覽器不支援websocket(如IE10以下)時就會連線失敗

遇到的問題

因為我們的伺服器有做LTM分流,要連接的伺服器會在第一次未帶cookie時,發送set-cookie並儲存這個client所連接的是那個server,接下來帶著這個cookie的request,LTM就會導到相同的伺服器。
而預設nodejs並不會儲存cookie,因此有可能握手時是分流到A伺服器,真正建立卻跑到B伺服器去,這時就會發生下面錯誤
probe transport "websocket" failed because of error: Error: websocket error

解決方案

設定websocket的header增加所需cookie

_ioManager = new io.Manager(config.host, {
        reconnection: false,
        reconnectionAttempts: 5,
        reconnectionDelay: 1000,
        extraHeaders: {
            Cookie:cookies
        }
    });

若只需在polling時增加header則使用

_ioManager.opts.transportOptions = {
            polling: {
                extraHeaders: {
                    'Cookie': cookies,
                }
            }
        };