[Reserved] using the HTML5 WebSocket build real-time Web applications

As the next generation of Web standards, HTML5 has many compelling new features like Canvas, local storage, multimedia programming interfaces, WebSocket, and so on. This one has "Web of TCP" said the WebSocket especially attract the attention of developers. WebSocket makes the emergence of the browser provides support for Socket become possible to provide a two-way channel based on a TCP connection between the browser and the server. Web developers can easily build real-time web applications using WebSocket, in the hands of developers from the addition of a two-edged magic weapon. This paper introduces the basic concepts of HTML5 WebSocket specification as well as trying to solve this problem, then introduces the basic principles and WebSocket programming interface. Next will be through a simple example to demonstrate how to implement a WebSocket application, and shows how WebSocket achieve perfect unity in a powerful and easy to use program. Finally, the current mainstream browsers support WebSocket conditions, limitations, and future prospects.

The dilemma of real-time Web applications

Information exchange process Web applications are typically client makes a request through the browser and the server for processing after receiving the request and review complete and return the results to the client, then the client browser information will be presented, such a mechanism for information change not particularly frequent application can still live in peace, but for those who require a relatively high real-time applications, such as online games, online securities, equipment monitoring, online broadcast news, RSS feeds push, etc., when the client browser ready when presenting the information, the information on the server side may be out of date. So keep the client and server-side synchronization information is a key element in real-time Web applications for Web developers is also a problem. Before WebSocket specification came out, developers want to implement these real-time Web applications have to use some compromise solutions, the most commonly used is polling (Polling) and Comet technology, Comet technology is actually improved polling techniques, can be subdivided into two implementations a long polling mechanism, called streaming technology. Here we briefly explain these types of technologies:

Polling :

This is the first kind of real-time Web applications program. The client at certain time intervals a request to the server, by way of frequent requests to synchronize the client and server side. The biggest problem of this synchronization scheme is that when a client initiates a request to a server at a fixed frequency, the data server may not be updated, it will bring a lot of unnecessary network traffic, so this is a very inefficient in real time Program.

Long polling:

Long polling polling timing is improved and enhanced, the purpose is to reduce the network transmission invalid. When the server does not update data, the connection will remain a period of time until the data or state change or expiration time, to reduce the interaction between the client and the server is invalid through this mechanism. Of course, if the server data changes very frequently, then this mechanism and timing of polling comparison does not improve the performance of the essence.

flow:

Streaming technology program is usually request a long connection to the server using the client's page in a hidden window. To respond after receiving the request and the server is updated with the state to ensure that the client and server-side connection of expiring. Information server can be continually on the client through this mechanism. This mechanism has on the user experience a little problem and needs to improve the user experience for different browsers different design, while such a mechanism in the case of concurrent relatively large, server-side resources is a great test.

Integrated these types of programs, you will find these so-called real-time technology that we currently use are not true real-time technology, they are just using Ajax way to simulate the real-time effect, when each client and server-side interaction are HTTP is a request and response process, and each time are HTTP requests and responses with full HTTP header information, which increases the amount of data of each transfer, and the programming of these programs client and server implementations complex, in practical applications, in order to simulate more realistic real-time effects, developers often requires HTTP connection configured to simulate two-way communication between a client and a server, a client is connected to the data transmission processing server , a connection for data transmission from the server to handle the client, which inevitably increases the complexity of programming, but also increases the load on the server side, restricts the scalability of the application system.

WebSocket rescue

HTML5 WebSocket designed purpose is to replace polling and Comet technology, the client browser with real-time communications capabilities like under C / S architecture of desktop systems. Sent to the browser via JavaScript WebSocket server request to establish a connection after the connection is established, the client and the server can directly exchange data via TCP connection. Because WebSocket connection is essentially a TCP connection, so in terms of size stability and data transfer amount data transmission, and the polling and Comet technology, compared with a significant performance advantage. Websocket.org website gave a detailed testing and comparison with the traditional way of polling and WebSocket call, a simple Web application using polling and WebSocket, respectively, to achieve, to quote it here their test results chart:

Figure 1. Comparison network load polling and WebSocket implementations

This can be clearly seen from the figure, in the case where the flow rate and the load increases, a WebSocket program has significant performance advantages compared to conventional polling scheme Ajax. This is also the reason why we think WebSocket is the preferred option of future real-time Web applications.

WebSocket specification

The WebSocket protocol is essentially a TCP-based protocol. In order to establish a WebSocket connection, the client browser initiates an HTTP server would first like to request that this request and the usual HTTP requests, the header contains some additional information, additional header information "Upgrade: WebSocket" indicates that this is a application protocol HTTP request, the server upgrade to resolve these additional header information and then generate a response message back to the client, WebSocket connection client and server is set up, the two sides through the transmission of information connecting channels free, and this connection will be persist until the client or server side of a party initiative to close the connection.

Below we explain in detail WebSocket specification, since the specification is still in draft form, version changes faster, we select draft-hixie-thewebsocketprotocol-76 version to describe the WebSocket protocol. Because this version is currently in the mainstream browsers such as Chrome ,, FireFox, Opera have been on good support, if you are referring to is the new version of some of the words, the content may be slightly different.

A typical example WebSocket initiation request and get a response looks as follows:

Listing 1. WebSocket protocol handshake

 1 客户端到服务端: 
 2 GET /demo HTTP/1.1 
 3 Host: example.com 
 4 Connection: Upgrade 
 5 Sec-WebSocket-Key2: 12998 5 Y3 1 .P00 
 6 Upgrade: WebSocket 
 7 Sec-WebSocket-Key1: 4@1 46546xW%0l 1 5 
 8 Origin: http://example.com 
 9 [8-byte security key] 
10 
11 服务端到客户端:
12 HTTP/1.1 101 WebSocket Protocol Handshake 
13 Upgrade: WebSocket 
14 Connection: Upgrade 
15 WebSocket-Origin: http://example.com 
16 WebSocket-Location: ws://example.com/demo 
17 [16-byte hash response]

These requests and HTTP requests are usually very similar, but some of the content is closely related to and WebSocket protocol. We need to briefly explain these request and response message, "Upgrade: WebSocket" indicates that this is a special HTTP request, the purpose of the request is to get the client and server communication protocol upgrade from the HTTP protocol to the WebSocket protocol. Information from the client to the server's request with "Sec-WebSocket-Key1", "Sec-WebSocket-Key2" and "[8-byte securitykey]" Such header information. This is to generate a 16-bit security key handshake process, the server needs to provide the client browser to the server-side parsing the header information, and in accordance with the handshake of this information and returned to the client, the server side gets to show the client's request, agreed to create a WebSocket connection. Once the connection is established, the client and the server can be transmitted via a bidirectional data channel of this.

In the actual development process, in order to interface to build Web applications using WebSocket, we first need to build a WebSocket specification implements the server, the server-side implementation is not limited by platform and development language, you only need to comply with WebSocket specification, now appears some of the more mature WebSocket server implementations, such as:

  • Kaazing WebSocket Gateway - WebSocket Server is a Java implementation
  • mod_pywebsocket - WebSocket Server is a Python implementation
  • Netty - Network framework which includes a Java implementation of the WebSocket support
  • node.js - JavaScript framework provides a Server-side WebSocket support

If more than WebSocket server implementation does not meet your business needs, then, developers can implement a server according to your own specifications WebSocket. In the "real WebSocket" In this section, we will use the C # language on the Microsoft .NET platform to create a simple WebSocket server, and then build a simple live chat system.

WebSocket JavaScript Interface

On one introduces WebSocket specification, which introduces the WebSocket handshake agreement. Handshake protocol is usually a problem when we build WebSocket server implementations and provides a browser WebSocket support to be considered, and for WebSocket Web developers JavaScript client interface is very simple, the following is defined JavaScript WebSocket interface:

Listing 2. WebSocket JavaScript definitions

 1 [Constructor(in DOMString url, in optional DOMString protocol)] 
 2  interface WebSocket { 
 3    readonly attribute DOMString URL; 
 4         // ready state 
 5    const unsigned short CONNECTING = 0; 
 6    const unsigned short OPEN = 1; 
 7    const unsigned short CLOSED = 2; 
 8    readonly attribute unsigned short readyState; 
 9    readonly attribute unsigned long bufferedAmount; 
10    //networking 
11    attribute Function onopen; 
12    attribute Function onmessage; 
13    attribute Function onclose; 
14    boolean send(in DOMString data); 
15    void close(); 
16  }; 
17  WebSocket implements EventTarget;

Wherein the attributes represent WebSocket server URL network address, a protocol typically "ws", send way is to send data to the server, Close is to close the connection. In addition to these methods, there are some very important events: onopen, onmessage, onerror and onclose. We borrow Nettuts to the image of the WebSocket interface to show you a map on the website:

Figure 2. WebSocket JavaScript Interface

Here is a simple piece of JavaScript code that shows how to establish a WebSocket connection and access to data:

Listing 3. JavaScript code to create an instance of WebSocket connection

 1  var  wsServer = 'ws://localhost:8888/Demo'; 
 2  var  websocket = new WebSocket(wsServer); 
 3  websocket.onopen = function (evt) { onOpen(evt) }; 
 4  websocket.onclose = function (evt) { onClose(evt) }; 
 5  websocket.onmessage = function (evt) { onMessage(evt) }; 
 6  websocket.onerror = function (evt) { onError(evt) }; 
 7  function onOpen(evt) { 
 8  console.log("Connected to WebSocket server."); 
 9  } 
10  function onClose(evt) { 
11  console.log("Disconnected"); 
12  } 
13  function onMessage(evt) { 
14  console.log('Retrieved data from server: ' + evt.data); 
15  } 
16  function onError(evt) { 
17  console.log('Error occured: ' + evt.data); 
18  }

Browser support

   The following are major browsers support the case for the HTML5 WebSocket:

Browser Support for
Chrome Supported in version 4+
Firefox Supported in version 4+
Internet Explorer Supported in version 10+
Opera Supported in version 10+
Safari Supported in version 5+

WebSocket 实战

这一节里我们用一个案例来演示怎么使用 WebSocket 构建一个实时的 Web 应用。这是一个简单的实时多人聊天系统,包括客户端和服务端的实现。客户端通过浏览器向聊天服务器发起请求,服务器端解析客户端发出的握手请求并产生应答信息返回给客户端,从而在客户端和服务器之间建立连接通道。服务器支持广播功能,每个聊天用户发送的信息会实时的发送给所有的用户,当用户退出聊天室时,服务器端需要清理相应用户的连接信息,避免资源的泄漏。以下我们分别从服务器端和客户端来演示这个 Web 聊天系统的实现,在实现方式上我们采用了 C# 语言来实现 WebSocket 服务器,而客户端是一个运行在浏览器里的 HTML 文件。

WebSocket 服务器端实现

这个聊天服务器的实现和基于套接字的网络应用程序非常类似,首先是服务器端要启动一个套接字监听来自客户端的连接请求,关键的区别在于 WebSocket 服务器需要解析客户端的 WebSocket 握手信息,并根据 WebSocket 规范的要求产生相应的应答信息。一旦 WebSocket 连接通道建立以后,客户端和服务器端的交互就和普通的套接字网络应用程序是一样的了。所以在下面的关于 WebSocket 服务器端实现的描述中,我们主要阐述 WebSocket 服务器怎样处理 WebSocket 握手信息,至于 WebSocket 监听端口的建立,套接字信息流的读取和写入,都是一些常用的套接字编程的方式,我们就不多做解释了,您可以自行参阅本文的附件源代码文件。

在描述 WebSocket 规范时提到,一个典型的 WebSocket Upgrade 信息如下所示:

1 GET /demo HTTP/1.1 
2 Host: example.com 
3 Connection: Upgrade 
4 Sec-WebSocket-Key2: 12998 5 Y3 1 .P00 
5 Upgrade: WebSocket 
6 Sec-WebSocket-Key1: 4@1 46546xW%0l 1 5 
7 Origin: http://example.com 
8 [8-byte security key]

其中 Sec-WebSocket-Key1,Sec-WebSocket-Key2 和 [8-byte security key] 这几个头信息是 WebSocket 服务器用来生成应答信息的来源,依据 draft-hixie-thewebsocketprotocol-76 草案的定义,WebSocket 服务器基于以下的算法来产生正确的应答信息:

  1. 逐个字符读取 Sec-WebSocket-Key1 头信息中的值,将数值型字符连接到一起放到一个临时字符串里,同时统计所有空格的数量;
  2. 将在第 1 步里生成的数字字符串转换成一个整型数字,然后除以第 1 步里统计出来的空格数量,将得到的浮点数转换成整数型;
  3. 将第 2 步里生成的整型值转换为符合网络传输的网络字节数组;
  4. 对 Sec-WebSocket-Key2 头信息同样进行第 1 到第 3 步的操作,得到另外一个网络字节数组;
  5. 将 [8-byte security key] 和在第 3,第 4 步里生成的网络字节数组合并成一个 16 字节的数组;
  6. 对第 5 步生成的字节数组使用 MD5 算法生成一个哈希值,这个哈希值就作为安全密钥返回给客户端,以表明服务器端获取了客户端的请求,同意创建 WebSocket 连接

至此,客户端和服务器的 WebSocket 握手就完成了,WebSocket 通道也建立起来了。下面首先介绍一下服务器端实现是如何根据用户传递的握手信息来生成网络字节数组的。.NET 平台提供了很方便的对字符串,数值以及数组操作的函数,所以生成字节数组的方法还是非常简单明了的,代码如下:

清单 4. 生成网络字节数组的代码

 1 private byte[]   BuildServerPartialKey(string clientKey) 
 2  { 
 3       string partialServerKey = ""; 
 4      byte[] currentKey; 
 5      int spacesNum = 0; 
 6      char[] keyChars = clientKey.ToCharArray(); 
 7      foreach (char currentChar in keyChars) 
 8      { 
 9          if (char.IsDigit(currentChar)) partialServerKey += currentChar; 
10         if (char.IsWhiteSpace(currentChar)) spacesNum++; 
11      } 
12      try 
13      { 
14               currentKey = BitConverter.GetBytes((int)(Int64.Parse(partialServerKey) 
15  / spacesNum)); 
16         if (BitConverter.IsLittleEndian) Array.Reverse(currentKey); 
17      } 
18      catch 
19      { 
20         if (currentKey!= null) Array.Clear(currentKey, 0, currentKey.Length); 
21      } 
22      return currentKey; 
23   }

得到网络字节数组以后,服务器端生成 16 位安全密钥的方法如下所示:

清单 5. 生成 16 位安全密钥的代码

 1  private byte[] BuildCompleteServerKey(byte[] serverKey1, byte[] serverKey2, 
 2  byte[] last8Bytes) 
 3  { 
 4      byte[] concatenatedKeys = new byte[16]; 
 5     Array.Copy(serverKey1, 0, concatenatedKeys, 0, 4); 
 6     Array.Copy(serverKey2, 0, concatenatedKeys, 4, 4); 
 7     Array.Copy(last8Bytes, 0, concatenatedKeys, 8, 8); 
 8     System.Security.Cryptography.MD5 MD5Service = 
 9  System.Security.Cryptography.MD5.Create(); 
10    return MD5Service.ComputeHash(concatenatedKeys); 
11  }

整个实现是非常简单明了的,就是将生成的网络字节数组和客户端提交的头信息里的 [8-byte security key] 合并成一个 16 位字节数组并用 MD5 算法加密,然后将生成的安全密钥作为应答信息返回给客户端,双方的 WebSocekt 连接通道就建立起来了。实现了 WebSocket 握手信息的处理逻辑,一个具有基本功能的 WebSocket 服务器就完成了。整个 WebSocket 服务器由两个核心类构成,一个是 WebSocketServer,另外一个是 SocketConnection,出于篇幅的考虑,我们不介绍每个类的属性和方法了,文章的附件会给出详细的源代码,有兴趣的读者可以参考。

服务器刚启动时的画面如下:

图 3. WebSocket 服务器刚启动的画面

客户端可以依据这个信息填写聊天服务器的连接地址,当有客户端连接到聊天服务器上时,服务器会打印出客户端和服务器的握手信息,每个客户的聊天信息也会显示在服务器的界面上,运行中的聊天服务器的界面如下:

图 4. 有客户端连接到 WebSocket 服务器的

以上我们简单描述了实现一个 WebSocket 服务器的最基本的要素,下一节我们会描述客户端的实现。

客户端实现

客户端的实现相对于服务器端的实现来说要简单得多了,我们只需要发挥想象去设计 HTML 用户界面,然后呼叫 WebSocket JavaScript 接口来和 WebSocket 服务器端来交互就可以了。当然别忘了使用一个支持 HTML5 和 WebSocket 的浏览器,在笔者写这篇文章的时候使用的浏览器是 Firefox。客户端的页面结构是非常简洁的,初始运行界面如下:

图 5. 聊天室客户端初始页面

当页面初次加载的时候,首先会检测当前的浏览器是否支持 WebSocket 并给出相应的提示信息。用户按下连接按钮时,页面会初始化一个到聊天服务器的 WebSocekt 连接,初始化成功以后,页面会加载对应的 WebSocket 事件处理函数,客户端 JavaScript 代码如下所示:

清单 6. 初始化客户端 WebSocket 对象的代码

 1 function ToggleConnectionClicked() {
 2           if (SocketCreated && (ws.readyState == 0 || ws.readyState == 1)) {  
 3                 ws.close();
 4             } else {
 5                 Log("准备连接到聊天服务器 ...");
 6                 try {
 7                  ws = 
 8                  new WebSocket("ws://" + document.getElementById("Connection").value);
 9                   SocketCreated = true;
10                 } catch (ex) {
11                   Log(ex, "ERROR");
12                   return;
13                 }
14                 document.getElementById("ToggleConnection").innerHTML = "断开";
15                 ws.onopen = WSonOpen;
16                 ws.onmessage = WSonMessage;
17                 ws.onclose = WSonClose;
18                 ws.onerror = WSonError;
19             }
20         };
21 
22         function WSonOpen() {
23             Log("连接已经建立。", "OK");
24             $("#SendDataContainer").show("slow");
25         };
26 
27         function WSonMessage(event) {
28             Log(event.data);            
29         };
30 
31         function WSonClose() {
32             Log("连接关闭。", "ERROR");
33             document.getElementById("ToggleConnection").innerHTML = "连接";
34             $("#SendDataContainer").hide("slow");
35         };
36 
37 
38         function WSonError() {
39             Log("WebSocket错误。", "ERROR");
40         };

当用户按下发送按钮,客户端会调用WebSocket对象向服务器发送信息,并且这个消息会广播给所有的用户,实现代码如下所示:

1 function SendDataClicked()
2  {
3             if (document.getElementById("DataToSend").value != "") {
4                 ws.send(document.getElementById("txtName").value + "说 :\"" + 
5 document.getElementById("DataToSend").value + "\"");
6                 document.getElementById("DataToSend").value = "";
7             }
8         };

如果有多个用户登录到聊天服务器,客户端页面的运行效果如下所示:

图 6. 聊天客户端运行页面
至此我们已经完成了一个完整的 WebSocket 客户端实现,用户可以体验一下这个聊天室的简单和快捷,完全不用考虑页面的刷新和繁琐的 Ajax 调用,享受桌面程序的用户体验。WebSocket 的强大和易用可见一斑,您完全可以在这个基础上加入更多的功能,设计更加漂亮的用户界面,切身体验 WebSocket 的震撼力。完整的客户端代码请参阅附件提供的源代码。

WebSocket 的局限性

WebSocket 的优点已经列举得很多了,但是作为一个正在演变中的 Web 规范,我们也要看到目前用 Websocket 构建应用程序的一些风险。首先,WebSocket 规范目前还处于草案阶段,也就是它的规范和 API 还是有变动的可能,另外的一个风险就是微软的 IE 作为占市场份额最大的浏览器,和其他的主流浏览器相比,对 HTML5 的支持是比较差的,这是我们在构建企业级的 Web 应用的时候必须要考虑的一个问题。

总结

This article describes the HTML5 WebSocket turned out as well as it tries to solve the problem, then introduces the WebSocket WebSocket specification and interfaces, as well as real-time technology compared to the traditional advantages in performance, and demonstrates how to use WebSocket to build a real-time Web applications, and finally we introduce the limitations of HTML5 WebSocket support of the current situation and major browsers. However, we should see that, despite the HTML5 WebSocket there are still some limitations, but is the general trend, Microsoft has clearly expressed support for HTML5 in the future, and these support we can see in Windows 8 and IE10, we are mobile devices, see figure HTML5 and WebSocket tablet. WebSocket will become a force in the future development of real-time Web applications should be no suspense, and as a Web developer, focus on HTML5, WebSocket attention should also be put on the agenda, otherwise we can only in the new round of the wave of software innovation do a view of the wall.

Source: Download

Reproduced in: https: //my.oschina.net/weisenz/blog/200626

Guess you like

Origin blog.csdn.net/weixin_34289454/article/details/91920902