WebSocket 一、编写WebSocket客户端
原文链接:Writing WebSocket client applications
WebSocket client应用程序通过WebSocket协议与WebSocket servers 通讯。
Note: 此功能可应用于 Web Workers。使用 Web Workers链接。
步骤:
1. 创建WebSocket对象。
要使用WebSocket 协议进行通信,需要创建一个 WebSocket 对象;创建WebSocket对象的过程,会自动尝试打开与服务器的连接。
WebSocket 构造函数要求一个必要参数url与一个可选参数protocol:
WebSocket WebSocket(
in DOMString url,
in optional DOMString protocols
);
url:
要连接的URL; 也就是用来响应的WebSocket server的URL。
protocols 可选:
一个string值类型的协议名称 或 一个string值类型的数组。这些字符串用于指示子协议,以便单个服务器可以实现多个WebSocket子协议(例如,您可能希望一个服务器能够根据指定的协议处理不同类型的交互)。 如果您不指定协议字符串,则假定为空字符串。
构造函数可能抛出的异常:
SECURITY_ERR
正在尝试连接的端口被阻塞。
连接错误
如果尝试连接时发生错误,首先会将名为“error”的简单事件发送给WebSocket对象(从而调用它的onerror处理程序),然后将CloseEvent发送给WebSocket对象(从而调用它的onclose处理程序) 以指出连接关闭的原因。
从Firefox 11开始,通常会在Mozilla平台的控制台中收到描述性错误消息,并通过CloseEvent收到RFC 6455第7.4节中定义的结束代码。
示例
这个例子创建了一个新的WebSocket,连接到WebSocket 服务器地址是ws://www.example.com/socketserver,协议是一个自定义协议”protocolOne”(可选项)。
var exampleSocket = new WebSocket("ws://www.example.com/socketserver", "protocolOne");
返回时,exampleSocket.readyState是CONNECTING。 一旦连接准备好传输数据,readyState将变为OPEN。
如果你想打开一个连接并且对你所支持的协议很灵活,你可以指定一个协议数组:
var exampleSocket = new WebSocket("ws://www.example.com/socketserver", ["protocolOne", "protocolTwo"]);
一旦建立了连接(即readyState是OPEN),exampleSocket.protocol会告诉你服务器选择了哪个协议。
在上面的例子中,http被ws取代,同样http被wss取代。 建立WebSocket依赖于HTTP Upgrade 机制,所以当我们发送HTTP请求ws://www.example.com或wss://www.example.com给服务器,协议会自动升级(不知道翻译的对不对)
下图说明的很清楚(来源):
步骤是
1,客户端(192.168.1.99:45836)发送请求到 服务器hoyo.idv.tw :80。
2,服务器根据请求的header(Upgrade: websocket),升级http协议为WebSocket并返回。
3,以上WebSocket建立后便于http没有任何关系了。之后使用WebSocket发送、接收消息都是通过socket通信(客户端 与 服务器端的连接端口与协议已改变),都是在客户端(192.168.1.99:47508)与服务器(ws://hoyo.idv.tw:1030)之间进行。
4,发送、接收消息 前后,都可以再跟进实际应用做判断:是否已认证?没认证不允许发消息?
2. 向服务器发送数据
1,建立连接后,可以通过WebSocket 对象的 send()方法发送数据。
exampleSocket.send("Here's some text that the server is urgently awaiting!");
发送的数据可以是字符串,也可以是 Blob, 或者 ArrayBuffer。
Note: Firefox 11版本,只支持发送 字符串 。
2,由于建立连接是异步的并且容易失败,因此不能保证在创建WebSocket对象之后立即调用send()方法将会成功。 但至少可以确定,可以通过定义onopen处理程序来实现:只在建立连接后,才会尝试发送数据。
exampleSocket.onopen = function (event) {
exampleSocket.send("Here's some text that the server is urgently awaiting!");
};
3,使用 JSON 传输对象
可以使用JSON将复杂的数据发送给服务器。 例如,聊天程序可以使用使用JSON-encapsulated(封装)数据包实现的协议与服务器交互:
// Send text to all users through the server
function sendText() {
// Construct a msg object containing the data the server needs to process the message from the chat client.
var msg = {
type: "message",
text: document.getElementById("text").value,
id: clientID,
date: Date.now()
};
// Send the msg object as a JSON-formatted string.
exampleSocket.send(JSON.stringify(msg));
// Blank the text input element, ready to receive the next line of text from the user.
document.getElementById("text").value = "";
}
4,接收服务器端的数据
考虑一下聊天客户端应用程序,它使用前面3中提及的JSON传输对象(Using JSON to transmit objects. )。 客户端可能会收到不同类型的数据包,如:
- Login handshake
- Message text
- User list updates
解释代码:
exampleSocket.onmessage = function(event) {
var f = document.getElementById("chatbox").contentDocument;
var text = "";
var msg = JSON.parse(event.data);
var time = new Date(msg.date);
var timeStr = time.toLocaleTimeString();
switch(msg.type) {
case "id":
clientID = msg.id;
setUsername();
break;
case "username":
text = "<b>User <em>" + msg.name + "</em> signed in at " + timeStr + "</b><br>";
break;
case "message":
text = "(" + timeStr + ") <b>" + msg.name + "</b>: " + msg.text + "<br>";
break;
case "rejectusername":
text = "<b>Your username has been set to <em>" + msg.name + "</em> because the name you chose is in use.</b><br>"
break;
case "userlist":
var ul = "";
for (i=0; i < msg.users.length; i++) {
ul += msg.users[i] + "<br>";
}
document.getElementById("userlistbox").innerHTML = ul;
break;
}
if (text.length) {
f.write(text);
document.getElementById("chatbox").contentWindow.scrollByPages(1);
}
};
这里我们使用JSON.parse()将JSON对象转换回原始对象,然后检查并处理其内容。
5,文本数据格式
通过WebSocket连接接收的文本采用UTF-8格式。
在Gecko 9.0(Firefox 9.0 / Thunderbird 9.0 / SeaMonkey 2.6)之前,某些有效的但不是字符的UTF-8文本,会导致连接被终止。 现在Gecko已允许这些值。
3.关闭连接
使用完WebSocket 连接,可使用 WebSocket close()方法关闭连接:
exampleSocket.close();
exampleSocket.close();
在关闭连接之前,可以使用 bufferedAmount
属性来检查是否有数据尚未在网络上传输数据。
4. 安全 注意事项
不应该在混合内容环境中使用WebSocket;也就是说,不应该从使用HTTPS加载的页面 打开不安全的WebSocket连接,反之亦然。 事实上,一些浏览器明确禁止这个,包括Firefox 8和更高版本。(https=>wss、http==>ws)
上一篇: websocket协议详解(2):websocket协议规范
下一篇: 运算符重载
推荐阅读
-
C#实现WebSocket协议客户端和服务器websocket sharp组件实例解析
-
使用WebSocket实现即时通讯(一个群聊的聊天室)
-
Python通过websocket与js客户端通信示例分析
-
基于SpringBoot+WebSocket搭建一个简单的多人聊天系统
-
PHP用swoole+websocket和redis实现web一对一聊天
-
Python实现同时兼容老版和新版Socket协议的一个简单WebSocket服务器
-
C#实现WebSocket协议客户端和服务器websocket sharp组件实例解析
-
Java开发之使用websocket实现web客户端与服务器之间的实时通讯
-
node.js中ws模块创建服务端和客户端,网页WebSocket客户端
-
spring boot websocket stomp 实现广播通信和一对一通信聊天