Websocket protocol judgment, handshake and feedback

Source: Internet
Author: User

The distribution of Message Centers is achieved through establishing a persistent connection between websocket and the backend server. The advantage of this method is to save network bandwidth, second, users can receive messages sent from the backend in real time. netty is used in the backend implementation. After stress testing, each server can withstand 0.5 million persistent connections, that is, 0.5 million users at the same time (only one persistent connection is established for each website user), and the performance is better.

To establish a persistent connection, the client needs to initiate a handshake with the server. The following is an example from Wikipedia:

Browser request:

 
GET/demo HTTP/1.1 HOST: Example. comconnection: UpgradeSec-WebSocket-Key2: 12998 5 Y3 1. p00Sec-WebSocket-Protocol: sampleupgrade: WebSocketSec-WebSocket-Key1: 4 @ 1 46546xw % 0l 1 5 origin: http://example.com ^ N: DS [4u

In the request, the "Sec-WebSocket-Key1", "Sec-WebSocket-Key2" and the last "^ N: DS [4u" are random, and the server uses the data to construct a 16-byte response. Where: ^ N: DS [4u is the request content, and others are the HTTP request header.

Note: Sec-WebSocket-Key1 and Sec-WebSocket-Key2 in the old websocket protocol is not, because to determine whether the current request is websocket, mainly through the request header inWhether connection is equal to upgrade and upgrade is equal to websocket. That is to say, to determine whether a request is a websocket request, you only need to determine the connection and upgrade in the request header, determine whether the old and new versions can be passed by including Sec-WebSocket-Key1 and Sec-WebSocket-Key2 ". The following is a short section to determine whether a websocket request is required.Code:

 
// Note: the code is netty-based private Boolean iswebsocketreq (httprequest req) {return (httpheaders. values. upgrade. equalsignorecase (req. getheader (httpheaders. names. connection) & httpheaders. values. websocket. equalsignorecase (req. getheader (httpheaders. names. upgrade )));}

Server Response:

HTTP/1.1 101 websocket protocol handshakeupgrade: websocketconnection: upgradesec-websocket-origin: http://example.comSec-websocket-location: WS: // your sample8jks 'y: G * CO, wxa-

Divide the number in the first key of the request by the number of blank characters in the first key, and the second key is the same. Connect the two results with the last 8-byte string of the request to form a string. The server responds to the body ("8jks 'y: G * CO, wxa -") that is, the MD5 sum of the string. The following is a netty-based response Java code:

// Netty-based websocket response code private httpresponse buildwebsocketres (httprequest req) {httpresponse res = new defaulthttpresponse (httpversion. http_1_1, new httpresponsestatus (101, "Web SOCKET protocol handshake"); Res. addheader (httpheaders. names. upgrade, httpheaders. values. websocket); Res. addheader (httpheaders. names. connection, httpheaders. values. upgrade); // fill in the headers and contents depending On handshake method. if (req. containsheader (names. sec_websocket_key1) & req. containsheader (names. sec_websocket_key2) {// draft 7.5, 7.6 and protocol standard // new handshake method with a challenge: Res. addheader (names. sec_websocket_origin, req. getheader (names. origin); Res. addheader (names. sec_websocket_location, getwebsocketlocation (req); string protocol = req. getheader (names. sec_websocket_protocol); If (protocol! = NULL) {res. addheader (names. sec_websocket_protocol, Protocol);} // calculate the answer of the challenge. string key1 = req. getheader (names. sec_websocket_key1); string key2 = req. getheader (names. sec_websocket_key2); int A = (INT) (Long. parselong (getnumeric (key1)/getspace (key1 ). length (); int B = (INT) (Long. parselong (getnumeric (key2)/getspace (key2 ). length (); long c = req. getcontent (). read Long (); channelbuffer input = channelbuffers. buffer (16); input. writeint (a); input. writeint (B); input. writelong (c); channelbuffer output = NULL; try {output = channelbuffers. wrappedbuffer (messagedigest. getinstance ("MD5 "). digest (input. array ();} catch (nosuchalgorithmexception e) {logger. error ("No such algorithm: MD5.", e) ;}res. setcontent (output);} else {// The oldest websocket protocol // old handshake me Thod with no challenge: If (req. getheader (names. Origin )! = NULL) {res. addheader (names. websocket_origin, req. getheader (names. origin);} res. addheader (names. websocket_location, getwebsocketlocation (req); string protocol = req. getheader (names. websocket_protocol); If (protocol! = NULL) {res. addheader (names. websocket_protocol, protocol) ;}} return res ;}// remove all non-numeric private string getnumeric (string Str) {return Str. replaceall ("\ D", "") ;}// return the space private string getspace (string Str) {return Str. replaceall ("\ s ","");}

Postscript:

Recently we found that chrome14 and ff6.5 use the latest websocket draft 10 Protocol. That is to say, the code in the above example does not support the handshake protocol of draft 10. The Protocol variable of the Draft operator is relatively large, for example, if the transmission is performed by frame and the frame bit has permission check, you can view my other article in detail.Article: Http://blog.csdn.net/fenglibing/article/details/6852497

This article is from:Feng Libin's blog

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.