【Web】WebSocket基础及使用

简介

介绍WebSocket之前需要先了解一个更基本的协议:超文本传输协议(Hyper Text Transfer Protocol,HTTP),它是一个简单的请求——响应协议,通常运行在TCP之上。

HTTP有一个问题:单向。即只能是客户端(浏览器)向服务器发送请求,服务器返回查询结果。如果服务器状态有连续的变化,就要求客户端进行轮询,这显然是效率很低的。

WebSocket就是用来解决HTTP的这个问题的,它是一种在单个TCP连接上进行全双工通信的协议。

下图是HTTP和WebSocket协议的实现差别:

在这里插入图片描述

WebSocket还有以下的特点:

  • 建立在TCP协议之上,服务器端的实现比较容易;
  • 与HTTP协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用HTTP协议,因此握手时不容易屏蔽,能通过各种HTTP代理服务器;
  • 数据格式比较轻量,性能开销小,通信高效;
  • 可以发送文本,也可以发送二进制数据;
  • 没有同源限制,客户端可以与任意服务器通信;
  • 协议标识符是ws(如果加密,则为wss),服务器网址也是URL,下面是一个示例:
ws://example.com:80/some/path

客户端代码接口

WebSocket客户端代码编写比较简单,直接通过JavaScript调用WebSocket接口即可,这里简单介绍。

构造函数

WebSocket(url[, protocols])

该函数返回一个 WebSocket对象。

url不用多介绍;protocols是可选的,是一个协议字符串或者一个包含协议字符串的数组,不确定有哪些值可用,不指定就是空字符。

常量

常量名
WebSocket.CONNECTING0
WebSocket.OPEN1
WebSocket.CLOSING2
WebSocket.CLOSED3

属性

属性名作用
WebSocket.binaryType使用二进制的数据类型连接。
WebSocket.bufferedAmount未发送至服务器的字节数。只读
WebSocket.extensions服务器选择的扩展。只读
WebSocket.onclose用于指定连接关闭后的回调函数。
WebSocket.onerror用于指定连接失败后的回调函数。
WebSocket.onmessage用于指定当从服务器接受到信息时的回调函数。
WebSocket.onopen用于指定连接成功后的回调函数。
WebSocket.protocol服务器选择的下属协议。只读
WebSocket.readyState当前的链接状态。只读
WebSocket.urlWebSocket 的绝对路径。只读

方法

WebSocket.close([code[, reason]])

关闭当前链接。

WebSocket.send(data)

对要传输的数据进行排队。

事件

使用 addEventListener() 可以监听下面的事件:

事件名作用
close当一个WebSocket连接被关闭时触发。
error当一个WebSocket连接因错误而关闭时触发,例如无法发送数据时。
message当通过WebSocket收到数据时触发。
open当一个WebSocket连接成功时触发。

上述事件也可以通过对应的onXXX属性来设置。

下面是一个示例:

// Create WebSocket connection.
const socket = new WebSocket('ws://localhost:8080');

// Connection opened
socket.addEventListener('open', function (event) {
    socket.send('Hello Server!');
});

// Listen for messages
socket.addEventListener('message', function (event) {
    console.log('Message from server ', event.data);
});

websocketd

服务器端示例

这里首先使用一款简单的WebSocket服务端程序作为WebSocket服务器来与客户端通信,这款程序是websocketd,可以在http://websocketd.com/下载到,Windows下得到的程序如下:

在这里插入图片描述

使用websocketd的一个最简单的例子如下:

websocketd.exe --port=8080 xxx

其中xxx是自己编写的程序。这个程序可以用很多的语言来编写,最主要的共同点是:输出即传输的数据。下面是一个c语言编写的例子:

#include <stdio.h>
#include <unistd.h>

int main() {
    int i;

    // 关闭缓冲
    setbuf(stdout, NULL);

    for (i = 0; i < 10; i++) {
        printf("%d\n", i);
        usleep(500000);
    }

    return 0;
}

注意这里的setbuf(stdout, NULL);是必不可少的,否则数据不会立即发送给浏览器WebSocket,而是等到程序结束之后才一起发送,在浏览器端就看不到预期的结果了。

如果直接执行该文件,就是每隔0.5秒打印一个从0开始递增的数字,结果如下:

在这里插入图片描述

这里将它作为websocketd.exe的参数:

websocketd.exe --port=8080 count.exe

这样就开起了一个WebSocket服务:

在这里插入图片描述

客户端编程示例

WebSocket客户端最常见的就是普通的浏览器,这里编写一个HTML网页,其实现中通过JavaScript编写WebSocket代码,示例如下:

<!DOCTYPE html>
<pre id="log"></pre>
<script>
    // 显示信息的帮助函数
    function log(msg) {
        document.getElementById('log').textContent += msg + '\n';
    }
    // 创建WebSocket
    var ws = new WebSocket('ws://localhost:8080/');
	// 连接创建时执行
    ws.onopen = function() {
        log('connected');
    };
    // 连接关闭时执行
    ws.onclose = function() {
        log('closed');
    };
    // 收到数据时执行
    ws.onmessage = function(event) {
        log('message: ' + event.data);
    };
</script>

直接在浏览器中打开该文件,执行结果如下:

在这里插入图片描述

这里的message将每隔0.5秒打印一次,结束之后打印closed,此时WebSocket的连接也断开了。

其它

以上是一个最简单的示例,该示例中传输的数据也是普通的字符,通过通用输入输出的拦截来完成传输,跟Web服务器类似。不过WebSocket还支持二进制,这个这里暂时不做演示。

另外,虽然说服务器端程序支持很多种语言,但是Python版本执行会报错:

在这里插入图片描述

原因不明。

另外websocketd的源码可以在https://github.com/joewalnes/websocketd下载到,它是Go语言编写的。

pywebsocket3

下载pywebsocket3,下载地址是https://github.com/GoogleChromeLabs/pywebsocket3

进入对应的目录执行构建、安装和使用:

在这里插入图片描述

之后通过浏览器访问:

在这里插入图片描述

上述显示来自pywebsocket的示例代码(通过-d .\example\指定)。

参考

  • https://www.ruanyifeng.com/blog/2017/05/websocket.html
  • https://developer.mozilla.org/zh-CN/docs/Web/API/WebSocket
  • http://websocketd.com/
  • https://github.com/GoogleChromeLabs/pywebsocket3/wiki
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值