如何让原生 WebSockets 在 Android 4.03 及更高版本中工作?

Posted

技术标签:

【中文标题】如何让原生 WebSockets 在 Android 4.03 及更高版本中工作?【英文标题】:How to get native WebSockets to work in Android 4.03 and above? 【发布时间】:2012-06-28 14:27:08 【问题描述】:

我一直在使用 web-socket-js 来支持跨设备的 websocket。在所有 ios 设备中运行良好,因为它们具有本机 web-socket 支持,并且在您安装了 flash 时在 android 设备中运行相当一致。现在,Android ICS 4.03 及更高版本声称支持原生网络套接字。 Window.WebSocket 已定义,但我没有打开套接字。有谁知道为什么? ICS 原生 websocket 有什么问题?他们使用什么协议?有没有人提出更好的解决方案?

=更新=

有一种方法可以确定 websocket 是否真的有效,然后回退到 flash。为此,您必须更改 web-socket-js 代码以检查它是否是 android 客户端。然后,在使用 web-socket 之前,尝试连接到本地机器上的一个端口。然后检查 websocket 的协议属性。如果已定义,那么您最好使用本机,否则回退到 Flash。仍在寻找更好的方法,但这是我现在正在使用的 hack:

例如:

   var isAndroid = navigator.userAgent.match(/Android/i) != null;
   var isChrome = navigator.userAgent.match(/Chrome/i) != null;

   // assume if its safari, that they use normal websockets.
   if ( isChrome || (!isAndroid && window.WebSocket)) 
          logger.log("Will attempt to use Websockets natively. 1");
          return;
   


   // check if we need a websocket fallback
   //if (window.WebSocket && !window.WEB_SOCKET_FORCE_FLASH) 
   if ( isAndroid ) 
          try 
                 var testSock = new window.WebSocket("ws://localhost:1474");
                 if (testSock.protocol != undefined) 
                       testSock.close();
                       logger.log("Will attempt to use Websockets natively. 2");
                       return;
                  else 
                       // use flash
                 
           catch (e) 
                 // if there was an error we need to use the flash fallback.
          
   

   logger.log("Native Websockets unavailable, trying Flash fallback...");

【问题讨论】:

根据caniuse ICS 不支持 WebSockets,您从哪里获得的信息? 在 ICS 4.03 和 4.04 WebSockets 中定义。但是,它并不完整。问题是 web-socket-js 认为原生 web-socket 是受支持的,因此不会退回到 flash。哦,我从调试器中获取了我的信息。 您应该将您的技巧添加为答案,而不是作为问题的编辑。 【参考方案1】:

因此,事实证明,我的问题中提到的 hack 实际上并不总是有效。一些 4.0.3 的 android 设备似乎支持本机 web-sockets,而其他设备不支持。我正在尝试确定这种差异是否存在于 4.0.3 附带的设备和升级的设备之间。我现在先检查是否支持 Flash 播放器,如果支持则使用它。如果没有,那么我检查android版本。如果它大于 4.0,我建议用户尝试在 chrome 中加载站点。否则,如果定义了 window.WebSocket,我会尝试使用它。

【讨论】:

我认为值得一提的是,并非所有网络都支持本机 websockets 协议! Orange 和 T-Mobile 通过 http 1.0 代理连接,这会在此处终止连接【参考方案2】:

Android 版 Chrome 支持 WS (RFC6455) - 它在 ICS 及更高版本上可用,但不支持标准浏览器。

至少 ARMv7 的 Android 设备上的 Firefox Mobile 支持 WS (RFC6455)。

Opera Mobile 在大多数 Android 设备上都支持 WS (Hixie76)。

推动谷歌:

让 Chrome for Android 在子 ICS 设备上可用 将 Android 版 Chrome 设为默认浏览器

【讨论】:

Opera 尚未在桌面 Opera 中默认启用,如果它在 Opera Mobile 上默认启用,我会感到惊讶。我怀疑这是你必须手动启用的配置。 对,要在桌面和移动 Opera 上启用 WebSocket (Hixie-76),请在地址栏中打开“opera:config#Enable%20WebSockets”。【参考方案3】:

伙计们,不要忘记在模拟设备时,避免在你的 android 项目的 config.xml 中定义“localhost”来访问你本地运行的 WS-Server。使用转换为 127.0.0.1 的定义的 10.0.2.2 地址(并​​确保您的 WS-Server 响应它)。 http://developer.android.com/tools/devices/emulator.html#emulatornetworking

【讨论】:

【参考方案4】:

从 4.X 开始的 Android 版本仅通过像 web-socket-js 这样的 Flash 模拟器支持 WebSockets 希望 4.1 (ICS) 将引入原生 WebSocket 支持。

也许是因为您正在加载模拟器而正在定义 window.WebSocket

【讨论】:

4.1 有 Chrome 作为默认浏览器,所以它会支持 WebSocket。 @robertc,目前我相信 Chrome 只会成为 4.1 平板电脑版本的默认浏览器。 Chrome 将可用于手机构建,但不是默认设置(不确定原因,可能是运营商的义务)。此外,就像 Safari 一样,不能保证任何给定的桌面功能都会在移动构建中启用,尽管我当然希望启用 WebSockets。 这不是我从周三的主题演讲中得到的印象,但我想唯一的选择就是观望。 @robertc,我看到了主题演讲,并专门听了它是无处不在的默认设置,他只说谷歌 Nexus 7。在这次采访中搜索“默认浏览器”:news.cnet.com/8301-17939_109-57463393-2/…Sundar 明确现在它只是 Google Nexus 7 上的默认设置,但暗示它最终将成为所有地方的默认设置。

以上是关于如何让原生 WebSockets 在 Android 4.03 及更高版本中工作?的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在原生 Android 应用程序中使用 WebSockets 或类似的?

使用 WebSockets 的反应原生应用程序中的架构

Django、websockets、Tornado,如何让它们通信?

是否提供对 Web Sockets 的原生 PHP 支持?

是否提供对 Web Sockets 的原生 PHP 支持?

如何使用棘轮 websockets 将数据发送到服务器 onload?