WebSocket Tutorial (Turn)

WebSocket Tutorial

Author: Ruan Yifeng

Date: May 15, 2017


WebSocket is a network communication protocol that is required for many advanced functions.

This article describes how to use the WebSocket protocol.

1. Why do you need WebSocket?

Anyone who is new to WebSockets asks the same question: we already have the HTTP protocol, why do we need another protocol? What benefits can it bring?

The answer is simple, because the HTTP protocol has a flaw: communication can only be initiated by the client.

For example, if we want to know today's weather, we can only make a request from the client to the server, and the server returns the query result. The HTTP protocol cannot allow the server to actively push information to the client.

The characteristics of this one-way request are destined to be very troublesome for the client to know if the server has continuous state changes. We can only use "polling" : every once in a while, a query is sent to see if the server has new information. The most typical scenario is the chat room.

Polling is inefficient and wastes resources (because you have to keep connecting, or the HTTP connection is always open). Therefore, engineers have been thinking, is there a better way. That's how WebSocket was invented.

2. Introduction

The WebSocket protocol was born in 2008 and became an international standard in 2011. All browsers already support it.

Its biggest feature is that the server can actively push information to the client, and the client can also actively send information to the server. It is a real two-way equal dialogue and belongs to a kind of server push technology .

Other features include:

(1) Based on the TCP protocol, the server-side implementation is relatively easy.

(2) It has good compatibility with the HTTP protocol. The default ports are also 80 and 443, and the HTTP protocol is used in the handshake phase, so it is not easy to shield during the handshake, and can pass through various HTTP proxy servers.

(3) The data format is relatively lightweight, the performance overhead is small, and the communication is efficient.

(4) Text can be sent, and binary data can also be sent.

(5) There is no same-origin restriction, and the client can communicate with any server.

(6) The protocol identifier is ws(if encrypted, it is wss) and the server URL is the URL.


ws://example.com:80/some/path

Third, the simple example of the client

The usage of WebSocket is fairly simple.

The following is an example of a web script (click here to see the running result), which can basically be understood at a glance.


var ws = new WebSocket("wss://echo.websocket.org");

ws.onopen = function(evt) { 
  console.log("Connection open ..."); 
  ws.send("Hello WebSockets!");
};

ws.onmessage = function(evt) {
  console.log( "Received Message: " + evt.data);
  ws.close();
};

ws.onclose = function(evt) {
  console.log("Connection closed.");
};      

Fourth, the client API

The API of the WebSocket client is as follows.

4.1 WebSocket Constructor

The WebSocket object is used as a constructor to create a new WebSocket instance.


var ws = new WebSocket('ws://localhost:8080');

After executing the above statement, the client will connect to the server.

For a list of all properties and methods of the instance object, see here .

4.2 webSocket.readyState

readyStateThe property returns the current state of the instance object, there are four kinds.

  • CONNECTING: A value of 0 means connecting.
  • OPEN: The value is 1, indicating that the connection is successful and communication is possible.
  • CLOSING: A value of 2 means the connection is closing.
  • CLOSED: The value is 3, indicating that the connection has been closed or failed to open the connection.

Below is an example.


switch (ws.readyState) {
  case WebSocket.CONNECTING:
    // do something
    break;
  case WebSocket.OPEN:
    // do something
    break;
  case WebSocket.CLOSING:
    // do something
    break;
  case WebSocket.CLOSED:
    // do something
    break;
  default:
    // this never happens
    break;
}

4.3 webSocket.onopen

Attribute of the instance object onopen, used to specify the callback function after the connection is successful.


ws.onopen = function () {
  ws.send('Hello Server!');
}

If you want to specify multiple callback functions, you can use addEventListenermethods.


ws.addEventListener('open', function (event) {
  ws.send('Hello Server!');
});

4.4 webSocket.onclose

Attribute of the instance object onclose, used to specify the callback function after the connection is closed.


ws.onclose = function(event) {
  var code = event.code;
  var reason = event.reason;
  var wasClean = event.wasClean;
  // handle close event
};

ws.addEventListener("close", function(event) {
  var code = event.code;
  var reason = event.reason;
  var wasClean = event.wasClean;
  // handle close event
});

4.5 webSocket.onmessage

Attribute of the instance object onmessage, used to specify the callback function after receiving server data.


ws.onmessage = function(event) {
  var data = event.data;
  // 处理数据
};

ws.addEventListener("message", function(event) {
  var data = event.data;
  // 处理数据
});

Note that server data may be text or binary data ( blobobject or Arraybufferobject).


ws.onmessage = function(event){
  if(typeof event.data === String) {
    console.log("Received data string");
  }

  if(event.data instanceof ArrayBuffer){
    var buffer = event.data;
    console.log("Received arraybuffer");
  }
}

In addition to dynamically judging the received data type, binaryTypeattributes can also be used to explicitly specify the received binary data type.


// 收到的是 blob 数据
ws.binaryType = "blob";
ws.onmessage = function(e) {
  console.log(e.data.size);
};

// 收到的是 ArrayBuffer 数据
ws.binaryType = "arraybuffer";
ws.onmessage = function(e) {
  console.log(e.data.byteLength);
};

4.6 webSocket.send()

The methods of the instance object are send()used to send data to the server.

Example of sending text.


ws.send('your message');

Example of sending a Blob object.


var file = document
  .querySelector('input[type="file"]')
  .files[0];
ws.send(file);

Example of sending an ArrayBuffer object.


// Sending canvas ImageData as ArrayBuffer
var img = canvas_context.getImageData(0, 0, 400, 320);
var binary = new Uint8Array(img.data.length);
for (var i = 0; i < img.data.length; i++) {
  binary[i] = img.data[i];
}
ws.send(binary.buffer);

4.7 webSocket.bufferedAmount

A property of the instance object bufferedAmountthat indicates how many bytes of binary data remain unsent. It can be used to determine whether the transmission is over.


var data = new ArrayBuffer(10000000);
socket.send(data);

if (socket.bufferedAmount === 0) {
  // 发送完毕
} else {
  // 发送还没结束
}

4.8 webSocket.onerror

Attribute of the instance object onerror, used to specify the callback function when an error is reported.


socket.onerror = function(event) {
  // handle error event
};

socket.addEventListener("error", function(event) {
  // handle error event
});

Five, the realization of the server

For implementations of WebSocket servers, see Wikipedia for a list .

There are three commonly used Node implementations.

For specific usage, please check their documentation, which is not described in detail here.

6. WebSocketd

Next, I want to recommend a very special WebSocket server: Websocketd .

Its biggest feature is that the background script is not limited to languages, the standard input (stdin) is the input of WebSocket, and the standard output (stdout) is the output of WebSocket.

For example, here is a Bash script counter.sh.


#!/bin/bash

echo 1
sleep 1

echo 2
sleep 1

echo 3

Running this script on the command line will output 1, 2, and 3 with a 1 second interval between each value.


$ bash ./counter.sh
1
2
3

Now, start websocketd, specifying this script as a service.


$ websocketd --port=8080 bash ./counter.sh

The above command will start a WebSocket server with port 8080. Whenever a client connects to this server, the counter.shscript is executed and its output is pushed to the client.


var ws = new WebSocket('ws://localhost:8080/');

ws.onmessage = function(event) {
  console.log(event.data);
};

The above is the client-side JavaScript code, which will output 1, 2, and 3 in the console after running.

With it, you can easily send the output of the command line to the browser.


$ websocketd --port=8080 ls

The above command will execute the lscommand to send the contents of the current directory to the browser. Using this method to monitor the server in real time is a breeze ( code ).

For more usage, please refer to the official example .

The essence of websocketd is the WebSocket proxy of the command line. As long as the program can be executed by the command line, it can communicate with the browser through WebSocket. Below is a Node implementation of the echo service greeter.js.


process.stdin.setEncoding('utf8');

process.stdin.on('readable', function() {
  var chunk = process.stdin.read();
  if (chunk !== null) {
    process.stdout.write('data: ' + chunk);
  }
});

The command to start this script is as follows.


$ websocketd --port=8080 node ./greeter.js

The official repository has examples in various other languages .

7. Reference link

(over)

Original link http://www.ruanyifeng.com/blog/2017/05/websocket.html

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326361244&siteId=291194637