【HTML5 API】Web套接字([HTML5 API] Web socket)

Web套接字

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

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

WebSocket API的使用非常简单。首先,通过WebSocket()构造函数创建一个套接字:
var socket = new WebSocket(“ws://ws.example.com:1234/resource”);

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

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

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

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

ws://
https://
wss://

创建了套接字之后,通常需要在上面注册一个事件处理程序:
socket.onopen = function(e) { /* 套接字已经连接 */ };
socket.onclose = function(e) { /* 套接字已经关闭.*/ };
socket.onerror = function(e) { /* 出错了 */ };
socket.onmessage = function(e) {
var message = e.data; /*服务器发送一条消息*/
};

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

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!”);

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

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

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

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

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

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

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

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来实现双向通信,而没有使用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);

下例是一个基于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);
————————

Web socket

Characteristics of HTTP protocol: it is a stateless protocol, which is composed of client request and server response. HTTP is actually a relatively special network protocol. Most Internet (or local area network) based network connections usually include long connections and two-way message exchange based on TCP sockets. It is not safe for untrusted client scripts to access the underlying TCP socket, but the websocket API defines a security scheme: it allows client code to create a two-way socket type connection between the client and the server supporting the websocket protocol. This makes some network operations easier.

Characteristics of HTTP protocol: it is a stateless protocol, which is composed of client request and server response. HTTP is actually a relatively special network protocol. Most Internet (or local area network) based network connections usually include long connections and two-way message exchange based on TCP sockets. It is not safe for untrusted client scripts to access the underlying TCP socket, but the websocket API defines a security scheme: it allows client code to create a two-way socket type connection between the client and the server supporting the websocket protocol. This makes some network operations easier.

The websocket API is very simple to use. First, create a socket through the websocket () constructor:
var socket = new WebSocket(“ws://ws.example.com:1234/resource”);
The parameter of the websocket() constructor is a URL that uses the protocol (or similar to the protocol used for secure links). The URL specifies the host to connect to, and may also specify the port (websocket uses the same default port as HTTP and HTTPS) and path or resource.

The websocket API is very simple to use. First, create a socket through the websocket () constructor:

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

The parameter of the websocket() constructor is a URL that uses the protocol (or similar to the protocol used for secure links). The URL specifies the host to connect to, and may also specify the port (websocket uses the same default port as HTTP and HTTPS) and path or resource.

ws://
https://
wss://

After creating a socket, you usually need to register an event handler on it:
Socket. Onopen = function (E) {/ * socket connected * /};
Socket. Onclose = function (E) {/ * socket has been closed. * /};
Socket. Onerror = function (E) {/ * error * /};
socket.onmessage = function(e) {
Var message = e.data; / * the server sends a message*/
};

After creating a socket, you usually need to register an event handler on it:

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

In order to send data to the server through the socket, you can call the send() method of the socket:
socket.send(“Hello, server!”);

In order to send data to the server through the socket, you can call the send() method of the socket:

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

The current version of websocket API only supports text messages and must be passed to the message as a string in UTF-8 encoding. However, the current websocket protocol also includes support for binary messages. Future versions of API may allow binary data exchange between the client and websocket server.

The current version of websocket API only supports text messages and must be passed to the message as a string in UTF-8 encoding. However, the current websocket protocol also includes support for binary messages. Future versions of API may allow binary data exchange between the client and websocket server.

After the communication with the server is completed, you can close the websocket by calling the close () method.

After the communication with the server is completed, you can close the websocket by calling the close () method.

Websocket is completely bidirectional, and once a websocket connection is established, the client and server can transmit messages to each other at any time. At the same time, this communication mechanism does not take the form of request and response. Each websocket based service should define its own “sub Protocol” to transmit data on the client and server. Slowly, these “sub protocols” may also evolve, and may eventually require the client and server to support multiple versions of sub protocols. Fortunately, the websocket protocol contains a negotiation mechanism for selecting sub protocols that both the client and the server can “understand”. You can pass an array of strings to the websocket () constructor. The server side will take the array as a list of sub protocols that the client can understand. It then selects one of the uses and passes it to the client. Once the connection is established, the client can detect which sub protocol is currently used through the protocol attribute of the socket.

Websocket is completely bidirectional, and once a websocket connection is established, the client and server can transmit messages to each other at any time. At the same time, this communication mechanism does not take the form of request and response. Each websocket based service should define its own “sub Protocol” to transmit data on the client and server. Slowly, these “sub protocols” may also evolve, and may eventually require the client and server to support multiple versions of sub protocols. Fortunately, the websocket protocol contains a negotiation mechanism for selecting sub protocols that both the client and the server can “understand”. You can pass an array of strings to the websocket () constructor. The server side will take the array as a list of sub protocols that the client can understand. It then selects one of the uses and passes it to the client. Once the connection is established, the client can detect which sub protocol is currently used through the protocol attribute of the socket.

An example is a simple chat client: it uses websocket to realize two-way communication, instead of using eventsource to obtain messages and XMLHttpRequest to send messages.
Example: chat client based on websocket
< script>
window.onload = function() {
//Care about some UI details
Var Nick = prompt (“enter your nickname”); / / get the user’s nickname
Var input = document.getelementbyid (“input”); / / find the input field
input.focus(); // Set cursor
//Open a websocket for sending and receiving chat messages
//Suppose the downloaded HTTP server operates as a websockem server and uses the same host name and port
//Only the protocol changed from htttp: / / to WS://
var socket = new WebSocket(“ws://” + location.host + “/”);
//The following shows how to get messages from the server through websocket
Socket. Onmessage = function (event) {/ / when a message is received
Var MSG = event. Data; / / get the message content from the event object
Var node = document. CreateTextNode (MSG); / / mark it as a text node
Var div = document.createelement (“div”); / / create a & lt; div & gt;
Div.appendchild (node); / / add a text node to the Div
Document. Body. InsertBefore (div, input); / / add the div before input
Input. Scrollintoview(); / / make sure the input box is visible
}
//The following shows how to send messages to the server through websocket
Input.onchange = function() {/ / when the user clicks enter
Var MSG = Nick + “:” + input.value; / / user’s nickname plus user’s input
Socket. Send (MSG); / / pass the content through the socket
Input. Value = “”; / / wait for more input
}
};
</ script>
<!– The chat window UI is very simple, with a wide text input field — & gt;
<!– A new chat message is inserted into the element — & gt;
< input id=”input” style=”width:100%”/>

An example is a simple chat client: it uses websocket to realize two-way communication, instead of using eventsource to obtain messages and XMLHttpRequest to send messages.

例:基于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%"/> 

The following example is a chat server based on websocket running in node. Websocket simplifies the server of chat application to be the same as the client.
Example: chat server using websocket and node
/*
*This is server-side JavaScript running on nodejs
*On top of the HTTP server, it runs a websocket server that wants to come from
* https://github.com/miksago/node-websocket-server/ Implementation of third-party websocket Library Based on
*If you get an HTTP request of “/”, the HTML file of the chat client will be returned
*In addition, any HTTP request returns 404
*Messages received through the websocket protocol are broadcast only to all active connections
*/
var http = require(‘http’); // Use HTTP server API of node
var ws = require(‘websocket-server’); // Using third-party websocket Libraries
//In the startup phase, read the resource file of the chat client
var clientui = require(‘fs’).readFileSync(“wschatclient.html”);
//Create an HTTP server
var httpserver = new http.Server();
//This function is run when the HTTP server gets a new request
httpserver.on(“request”, function (request, response) {
//If “/” is requested, the client chat UI is returned
If (request. Url = = = “/”) {/ / request chat UI
response.writeHead(200, (“Content-Type”: “text/html”});
response.write(clientui);
response.end();
}
Else {/ / 404 “cannot be found” code is returned for any other request
response.writeHead(404);
response.end();
}
});
//Wrap a websocket server on the HTTP server
var wsserver = ws.createServer({server: httpserver});
//This function is called when a new connection request is received
wsserver.on (“connection**, function(socket) (
Socket. Send (“welcome to the chat room.”); / / say hello to the new client
socket.on(“message”, function(msg) { // Listen for messages from clients
wsserver. broadcast (msg); // And broadcast them to everyone
});
});
//Run the server on port 8000. The HTTP server will also be started when the websocket server is started
//Connect to http://localhost:8000/ , and start using it
wsserver.listen(8000);

The following example is a chat server based on websocket running in node. Websocket simplifies the server of chat application to be the same as the client.

例: 使用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);