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)

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值