【HTML5 API】Web套接字

Web套接字

HTTP协议的特性:它是一种无状态的协议,由客户端请求和服务端响应组成。HTTP实际上是相对比较特殊的网络协议。大多数基于因特网(或者局域网)的网络连接通常都包含长连接和基于TCP套接字的双向消息交换。让不信任的客户端脚本访问底层的TCP套接字是不安全的,但是WebSocket API定义了一种安全方案:它允许客户端代码在客户端和支持WebSocket协议的服务器端创建双向的套接字类型的连接。这让某些网络操作会变得更加简单。

WebSocket API的使用非常简单。首先,通过WebSocket()构造函数创建一个套接字:

var socket = new WebSocket("ws://ws.example.com:1234/resource");

WebSocket()构造函数的参数是一个URL,该URL使用ws://协议(或者类似于https://用于安全链接的wss://协议)。该URL指定要连接的主机,还有可能指定端口(WebSocket使用和HTTP以及HTTPS一样的默认端口)和路径或者资源。

创建了套接字之后,通常需要在上面注册一个事件处理程序:

socket.onopen = function(e) { /* 套接字已经连接 */ };
socket.onclose = function(e) { /* 套接字已经关闭.*/ };
socket.onerror = function(e) { /* 出错了 */ };
socket.onmessage = function(e) {
 var message = e.data; /*服务器发送一条消息*/
};

为了通过套接字发送数据给服务器,可以调用套接字的send()方法:

socket.send("Hello, server!");

当前版本的WebSocket API仅支持文本消息,并且必须以UTF-8编码形式的字符串传递给该消息。然而,当前WebSocket协议还包含对二进制消息的支持,未来版本的API可能会允许在客户端和WebSocket服务器端进行二进制数据的交换。

当完成和服务器的通信之后,可以通过调用close()方法来关闭WebSocket。

WebSocket完全是双向的,并且一旦建立了WebSocket连接,客户端和服务器端都可以在任何时候互相传送消息,与此同时,这种通信机制采用的不是请求和响应的形式。每个基于WebSocket的服务都要定义自己的“子协议”,用于在客户端和服务器端传输数据。慢慢的,这些“子协议”也可能发生演变,可能最终要求客户端和服务器端需要支持多个版本的子协议。幸运的是,WebSocket协议包含一种协商机制,用于选择客户端和服务器端都能“理解”的子协议。可以传递一个字符串数组给WebSocket()构造函数。服务器端会将该数组作为客户端能够理解的子协议列表。然后,它会选择其中一个使用,并将它传递给客户端。一旦连接建立之后,客户端就能够通过套接字的protocol属性检测当前在使用的是哪种子协议。

例就是一个简单的聊天客户端:它采用了WebSocket来实现双向通信,而没有使用EventSource来获取消息以及XMLHttpRequest来发送消息。

例:基于WebSocket的聊天客户端

<script>
window.onload = function() {
    // 关心一些UI细节
    var nick = prompt("Enter your nickname");         // 获取用户昵称 
    var input = document.getElementById("input");     // 査找input字段 
    input.focus();	                                  // 设置光标
    
    // 打开一个WebSocket,用于发送和接收聊天消息
    // 假设下载的HTTP服务器作为WebSockem务器运作,并且使用同样的主机名和端口 
    // 只是协议由htttp://变成ws://
    var socket = new WebSocket("ws://" + location.host + "/");
    
    // 下面展示了如何通过WebSocket从服务器获取消息
    socket.onmessage = function(event) {             // 当收到一条消息
        var msg = event.data;                        // 从事件对象中获取消息内容
        var node = document.createTextNode(msg);     // 将它标记为一个文本节点
        var div = document.createElement("div");     // 创建一个<div>
        div.appendChild(node);                       // 将文本节点添加到该div中
        document.body.insertBefore(div, input);      // 在input前添加该div
        input.scrollIntoView();                      // 确保输入框可见
    }
    
    // 下面展示了如何通过WebSocket发送消息给服务器端
    input.onchange = function() {                    // 当用户敲击回车键 
        var msg = nick + ": " + input.value;         // 用户昵称加上用户的输入
        socket.send(msg);                            // 通过套接字传递该内容
        input.value = "";                            // 等待更多内容的输入
    }
};
</script>
<!-- 聊天窗口UI很简单,一个宽的文本输入域 --> 
<!-- 新的聊天消息会插入在该元素中 -->
<input id="input" style="width:100%"/> 

下例是一个基于WebSocket的聊天服务器,运行在Node中。WebSocket将聊天应用的服务端简化成和客户端一样。

例: 使用WebSocket和Node的聊天服务器
/*
 * 这是运行在NodeJS上的服务器端JavaScript
 * 在HTTP服务器之上,它运行一个WebSocket服务器,该服务器使想来自
 * https://github.com/miksago/node-websocket-server/ 的第三方WebSocket库实现
 * 如果得到"/"的一个HTTP请求,则返回聊天客户端的HTML文件
 * 除此之外任何HTTP请求都返回404
 * 通过WebSocket协议接收到的消息都仅广播给所有激活状态的连接
 */
var http = require('http');	              // 使用Node的HTTP服务器API
var ws = require('websocket-server');     // 使用第三方WebSocket库

// 启动阶段,读取聊天客户端的资源文件
var clientui = require('fs').readFileSync("wschatclient.html");

// 创建一个HTTP服务器
var httpserver = new http.Server();

// 当HTTP服务器获得一个新请求时,运行此函数
httpserver.on("request", function (request, response) {
    // 如果请求"/",则返回客户端聊天UI
    if (request.url === "/") { // 请求聊天UI
        response.writeHead(200, ("Content-Type": "text/html"}); 
        response.write(clientui);
        response.end();
    }
    
    else { //对任何其他的请求返回404"无法找到"编码
        response.writeHead(404);
        response.end();
    }
});

// 在HTTP服务器上包装一个WebSocket服务器
var wsserver = ws.createServer({server: httpserver});

// 当接收到一个新的连接请求的时候,调用此函数
wsserver.on ("connection**, function(socket) (
    socket.send("Welcome to the chat room.");     // 向新客户端打招呼 
    socket.on("message", function(msg) {	     // 监听来自客户端的消息
        wsserver. broadcast (msg);	              // 并将它们广播给每个人
    });
});

// 在8000端口运行服务器。启动WebSocket服务器的时候也会启动HTTP服务器 
// 连接到http://localhost:8000/,并开始使用它
wsserver.listen(8000);
上一篇:Html中设置访问页面不在后进行其他页面跳转


下一篇:Vue项目中使用websocket