iOS 上的 WebSocket
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5574385/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WebSockets on iOS
提问by probablyCorey
I've read that WebSockets work on iOS 4.2 and above. And I can verify that there is indeed a WebSocket object. But I can't find a single working WebSocket example that works on the phone.
我读过 WebSockets 在 iOS 4.2 及更高版本上工作。我可以验证确实有一个 WebSocket 对象。但是我找不到一个可以在手机上运行的 WebSocket 示例。
For example http://yaws.hyber.org/websockets_example.yawswill crash the Mobile Safari app. Has anyone got WebSockets working successfully on the phone?
例如http://yaws.hyber.org/websockets_example.yaws会使 Mobile Safari 应用程序崩溃。有没有人让 WebSockets 在手机上成功运行?
回答by probablyCorey
I may have found the solution. Mobile Safari only crashes with websockets when you have setup a proxy over wifi.
我可能已经找到了解决方案。当您通过 wifi 设置代理时,Mobile Safari 只会因 websockets 崩溃。
回答by moka
It is supported, but bear in mind regarding the standard that iOS Safari browser implements, it is not RFC 6455, but HyBi-00/Hixie-76.
它受支持,但请记住,iOS Safari 浏览器实现的标准不是 RFC 6455,而是 HyBi-00/Hixie-76。
You can test as well using this browser: http://websocketstest.com/
您也可以使用此浏览器进行测试:http: //websocketstest.com/
As well check this great post that have most of info regarding versions: https://stackoverflow.com/a/2700609/1312722
还可以查看这篇包含有关版本的大部分信息的精彩帖子:https: //stackoverflow.com/a/2700609/1312722
OBS!, this is an old answer. I have checked through the webpage mentioned in this post combined with browserstack.com:
OBS!,这是一个旧答案。我已经检查了这篇文章中提到的网页结合 browserstack.com:
- iPhone4S
- iPhone5
- iPhone5S
- iPhone6
- iPhone6 Plus
- iPhone6S
- iPhone6S Plus
- iPhone4S
- iphone 5
- iPhone 5S
- iPhone 6
- iPhone6 Plus
- iPhone6S
- iPhone6S Plus
All using RFC 6455
所有使用 RFC 6455
回答by Matthew Levine
I had a similar problem and even looked to this post to find a fix for it. For me, it had nothing to do with being on a wifi connection. It appears to be a bug in the iOS implementation of websockets (even up to the current version 5.1). Turning on a bunch of XCode's debugging I found that it has something to do with memory management because I would get something along the lines of "message sent to a deallocated instance." Most likely there was an object that didn't have the correct reference count and was cleaned up way too early.
我遇到了类似的问题,甚至查看了这篇文章以找到解决方法。对我来说,这与使用 wifi 连接无关。它似乎是 websockets 的 iOS 实现中的一个错误(甚至直到当前版本 5.1)。打开一堆 XCode 的调试,我发现它与内存管理有关,因为我会得到一些类似于“消息发送到释放的实例”的信息。很可能有一个对象没有正确的引用计数并且过早清理。
This blog has a lot of great information about the symptoms of the problem and how to debug it, but doesn't have a workaround: http://dalelane.co.uk/blog/?p=1652
这个博客有很多关于问题症状和如何调试它的重要信息,但没有解决方法:http: //dalelane.co.uk/blog/?p= 1652
Eventually though, I found this workaround, and my app has almost entirely stopped crashing now.
最终,我找到了这个解决方法,我的应用程序现在几乎完全停止崩溃了。
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); };
回答by Micka?l C. Guimar?es
I got them working on Chrome and Safari, iPhone and iPad (and other mobile devices too, but I guess you don't mind about them). Here is the Javascript code I am using :
我让他们在 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);
Sending data from client to server is done calling doSend() function. Receiving data from server also works, I've tested it from a custom C++ server.
从客户端向服务器发送数据是通过调用 doSend() 函数完成的。从服务器接收数据也有效,我已经从自定义 C++ 服务器对其进行了测试。
回答by Durai Amuthan.H
Here is a working sample
这是一个工作示例
Web socket client
网络套接字客户端
<!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 server
网络套接字服务器
Creating your own socket server is also simple Just install the Node.jsand socket.iothen proceed to install web socket via npm
创建自己的套接字服务器也很简单 只需安装Node.js和socket.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.');
});
});
save the above file as .js and run it like node filename.jsfrom terminal or command prompt
将上述文件另存为 .js 并像node filename.js 一样从终端或命令提示符运行它
The above file is like we have first created a http server using node then we're passing the created http server instance to Websocketserver then subsequently to Socket.iO instance
上面的文件就像我们首先使用 node 创建了一个 http 服务器,然后我们将创建的 http 服务器实例传递给 Websocketserver 然后再传递给 Socket.iO 实例
回答by Justin Bullard
I was debugging a similar issue and found that if you have used https to get the web page iOS will trap if you use the pass a the "ws:" protocol into WebSocket. If you use "wss:" everything will work and there will be no traps.
我正在调试一个类似的问题,发现如果您使用 https 来获取网页,如果您将“ws:”协议传递给 WebSocket,iOS 将陷入困境。如果你使用 "wss:" 一切都会正常并且不会有陷阱。