【问题标题】:WebSockets on iOSiOS 上的 WebSocket
【发布时间】:2011-07-31 06:29:31
【问题描述】:

我听说 WebSockets 可以在 iOS 4.2 及更高版本上运行。而且我可以验证确实有一个 WebSocket 对象。但是我找不到一个可以在手机上运行的 WebSocket 示例。

例如,http://yaws.hyber.org/websockets_example.yaws 将使 Mobile Safari 应用程序崩溃。有没有人让 WebSockets 在手机上成功运行?

【问题讨论】:

  • 您的示例在我的 iPod 4.2.1 (8C148) 上运行良好。通过 WiFi 连接。
  • 刚刚添加了“iphone”标签,让您获得更多关注;)
  • 在我的情况下(英国)使用 3G 无法正常工作,但使用 Safari、iPad 2 时 WiFi 运行良好。
  • 关于 Safari websocket 实现需要了解的一点是,与其他所有浏览器不同,如果 Basic Auth 已使用 https 方案完成,则 Safari 不会发送带有 Websocket 连接的 Basic Auth 标头。

标签: iphone ios ipad websocket


【解决方案1】:

我可能已经找到了解决方案。只有当您通过 wifi 设置代理时,Mobile Safari 才会与 websockets 崩溃。

【讨论】:

  • 一旦你被允许,不要忘记接受你的答案,以便其他人可以找到它。 :)
【解决方案2】:

支持,但请注意 iOS Safari 浏览器执行的标准不是 RFC 6455,而是 HyBi-00/Hixie-76。

您也可以使用此浏览器进行测试:http://websocketstest.com/

同时查看这篇包含大部分版本信息的精彩帖子:https://stackoverflow.com/a/2700609/1312722


OBS!,这是一个旧答案。 我已经检查了这篇文章中提到的网页以及 browserstack.com:

  • iPhone4S
  • iPhone5
  • iPhone5S
  • iPhone6
  • iPhone6 Plus
  • iPhone6S
  • iPhone6S Plus

全部使用RFC 6455

【讨论】:

  • 我使用 websocket.org/echo.html 进行测试,因为 websockets 测试对我来说似乎不适用于 wss:// 并且 websocket.org 为您提供了一些可以在文件中运行的简单 JavaScript 代码://或在您自己的网站上。
【解决方案3】:

我遇到了类似的问题,甚至查看了这篇文章以找到解决方法。对我来说,这与 wifi 连接无关。这似乎是 websockets 的 iOS 实现中的一个错误(甚至直到当前版本 5.1)。打开一堆 XCode 的调试,我发现它与内存管理有关,因为我会得到类似于“发送到已释放实例的消息”的内容。很可能有一个对象没有正确的引用计数并且被清理得太早了。

这个博客有很多关于问题症状和调试方法的重要信息,但没有解决方法:http://dalelane.co.uk/blog/?p=1652

最终,我找到了这个解决方法,我的应用现在几乎完全停止崩溃了。

me = this // strange javascript convention
this.socket = new WebSocket(url);
// put onmessage function in setTimeout to get around ios websocket crash
this.socket.onmessage = function(evt) { setTimeout(function() {me.onMessageHandler(evt);}, 0); };

【讨论】:

【解决方案4】:

我让他们在 Chrome 和 Safari、iPhone 和 iPad(以及其他移动设备上,但我猜你不介意它们)上工作。这是我正在使用的 Javascript 代码:

<script language="javascript" type="text/javascript">

    var wsUri = document.URL.replace("http", "ws");
    var output;
    var websocket;


    function init()
    {
        output = document.getElementById("output");
        wsConnect();
    }

    function wsConnect()
    {
        console.log("Trying connection to " + wsUri);
        try
        {
            output = document.getElementById("output");
            websocket = new WebSocket(wsUri);
            websocket.onopen = function(evt)
            {
                    onOpen(evt)
            };
            websocket.onclose = function(evt)
            {
                    onClose(evt)
            };
            websocket.onmessage = function(evt)
            {
                    onMessage(evt)
            };
            websocket.onerror = function(evt)
            {
                    onError(evt)
            };
        }
        catch (e)
        {
            console.log("Exception " + e.toString());
        }
    }


    function onOpen(evt)
    {
        alert("Connected to " + wsUri);
    }

    function onClose(evt)
    {
        alert("Disconnected");
    }

    function onMessage(evt)
    {
        alert('Received message : ' + evt.data);
    }

    function onError(evt)
    {
        alert("Error : " + evt.toString());
    }

    function doSend(message)
    {
        websocket.send(message);
    }

    window.addEventListener("load", init, false);

从客户端向服务器发送数据是通过调用 doSend() 函数完成的。从服务器接收数据也可以,我已经从自定义 C++ 服务器对其进行了测试。

【讨论】:

    【解决方案5】:

    这是一个工作示例

    Web 套接字客户端

    <!DOCTYPE html>
    <meta charset="utf-8" />
    <head>
    <title>WebSocket Test</title>
    <script language="javascript" type="text/javascript">
    
        var websocket;
    
    function OpenWebSocket()
    {
    
       try {
           websocket = new WebSocket(document.getElementById("wsURL").value);
           websocket.onopen = function(evt) { onOpen(evt) };
           websocket.onclose = function(evt) { onClose(evt) };
           websocket.onmessage = function(evt) { onMessage(evt) };
           websocket.onerror = function(evt) { onError(evt) };
       }
       catch(err) {
           writeToScreen(err.message);
       }
    }
    
    function CloseWebSocket()
    {
         websocket.close();
    }
    
    function FindWebSocketStatus()
    {
         try {
             if (websocket.readyState == 1){
              writeToScreen("Websocket connection is in open state")
             }
             else if (websocket.readyState == 0){
                 writeToScreen("Websocket connection is in connecting state")
             }
             else{
              writeToScreen("Websocket connection is in close state")
             }
         }
         catch(err) {
             writeToScreen(err.message);
         }
    }
    
    function FindWebSocketBufferedAmount(){
        try {
                writeToScreen(websocket.bufferedAmount)
        }
        catch(err) {
            writeToScreen(err.message);
        }
    }
    
    function SendMessageThroughSocket(){
        doSend(document.getElementById("wsMessage").value);
    }
    
    function onOpen(evt)
    {
        writeToScreen("Socket Connection Opened");
    }
    
    function onClose(evt)
    {
        writeToScreen("Socket Connection Closed");
    }
    
    function onMessage(evt)
    {
        writeToScreen('<span style="color: blue;">SERVER RESPONSE: ' + evt.data+'</span>');
    }
    
    function onError(evt)
    {
        writeToScreen('<span style="color: red;">ERROR:</span> ' + evt.data);
    }
    
    function doSend(message)
    {
        try{
        writeToScreen("CLIENT SENT: " + message);
        websocket.send(message);
        }
        catch(err) {
            writeToScreen(err.message);
        }
    }
    
    function writeToScreen(message)
    {
        var output = document.getElementById("output");
        var pre = document.createElement("p");
        pre.style.wordWrap = "break-word";
        pre.innerHTML = message;
        output.appendChild(pre);
    }
    </script>
    </title>
    </head>
    <body>
        <table>
            <tr>
                <td>
                    WebSocket URL
                </td>
                <td>
                    <input type="text" id="wsURL" value="ws://echo.websocket.org/"/>
                </td>
            </tr>
            <tr>
                <td>
                    WebSocket Message
                </td>
                <td>
                    <input type="text" id="wsMessage" value="Hi"/>
                </td>
            </tr>
            <tr>
                <td colspan="2" style="text-align:left;">
                    <input type="button" value="Open Socket Connection" onclick="OpenWebSocket();"/>
                </td>
            </tr>
            <tr>
                <td colspan="2" style="text-align:left;">
                     <input type="button" value="Send Message" onclick="SendMessageThroughSocket();"/>
                </td>
            </tr>
            <tr>
              <td colspan="2" style="text-align:left;">
                  <input type="button" value="Close Socket Connection" onclick="CloseWebSocket();"/>
              </td>
             </tr>
            <tr>
                <td colspan="2" style="text-align:left;">
                    <input type="button" value="Find Socket Status" onclick="FindWebSocketStatus();"/>
                </td>
            </tr>
            <tr>
                <td colspan="2" style="text-align:left;">
                    <input type="button" value="Find Socket Buffered Amount" onclick="FindWebSocketBufferedAmount();"/>
                </td>
            </tr>
        </table>
    
    <div id="output"></div>
    </body>
    </html>
    

    Web Socket 服务器

    创建自己的套接字服务器也很简单只需安装 Node.jssocket.io 然后继续通过 npm 安装 web socket

    #!/usr/bin/env node
    var WebSocketServer = require('websocket').server;
    var http = require('http');
    
    var server = http.createServer(function(request, response) {
                                   console.log((new Date()) + ' Received request for ' + request.url);
                                   response.writeHead(404);
                                   response.end();
                                   });
    server.listen(8888, function() {
                  console.log((new Date()) + ' Server is listening on port 8888');
                  });
    
    wsServer = new WebSocketServer({
                                   httpServer: server,
                                   // You should not use autoAcceptConnections for production
                                   // applications, as it defeats all standard cross-origin protection
                                   // facilities built into the protocol and the browser.  You should
                                   // *always* verify the connection's origin and decide whether or not
                                   // to accept it.
                                   autoAcceptConnections: false
                                   });
    
    function originIsAllowed(origin) {
        // put logic here to detect whether the specified origin is allowed.
        return true;
    }
    
    wsServer.on('request', function(request) {
                if (!originIsAllowed(request.origin)) {
                // Make sure we only accept requests from an allowed origin
                request.reject();
                console.log((new Date()) + ' Connection from origin ' + request.origin + ' rejected.');
                return;
                }
    
                var connection = request.accept();
                console.log((new Date()) + ' Connection accepted.');
                connection.on('message', function(message) {
                              if (message.type === 'utf8') {
                              console.log('Received Message: ' + message.utf8Data);
                              connection.sendUTF('Message received at server:'+message.utf8Data);
                              }
                              else if (message.type === 'binary') {
                              console.log('Received Binary Message of ' + message.binaryData.length + ' bytes');
                              connection.sendBytes(message.binaryData);
                              }
                              });
                connection.on('close', function(reasonCode, description) {
                              console.log((new Date()) + ' Peer ' + connection.remoteAddress + ' disconnected.');
                              });
                });
    

    将上述文件保存为 .js 并像 node filename.js 从终端或命令提示符运行它

    上面的文件就像我们首先使用节点创建了一个http服务器,然后我们将创建的http服务器实例传递给Websocketserver,然后再传递给Socket.iO实例

    【讨论】:

      【解决方案6】:

      我正在调试一个类似的问题,发现如果你使用 https 来获取网页,如果你使用将“ws:”协议传递给 WebSocket,iOS 将陷入陷阱。如果你使用“wss:”,一切都会正常工作,不会有任何陷阱。

      【讨论】:

        猜你喜欢
        • 2019-11-06
        • 2016-07-14
        • 2016-04-26
        • 1970-01-01
        • 2021-02-21
        • 2021-09-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多