当前位置: 首页 > news >正文

WebSocket快速入门及基本使用

        近期工作中经常使用到WebSocket协议,所以和大家分享一下WebSocket的相关内容,也借此机会整理一下自己的思绪。

HTTP协议(半双工通信)       

         介绍 WebSocket 前 我们先看看常用的HTTP协议,HTTP是客户端/服务器模式中请求-响应所用的协议,这种模式是半双工通信,浏览器向服务器提交HTTP请求,服务器响应请求的资源。简单说就是浏览器请求,服务器才响应。所以半双工通信的特点就是:

  • 同一时刻数据流是单向的,客户端向服务端请求数据->单向,服务端向客户端返回数据->单向
  • 服务器无法主动推送数据给客户端

        这种半双工通信你觉得是否存在局限呢,肯定是有的,因为同一时刻数据是单向的,有时候项目需求是希望服务器能够主动给客户端发送数据,为解决这一问题,在HTML5中又引入了一个双方能够同时通信的API,那就是WebSocket!

WebSocket协议(全双工通信)

        WebSocket是  HTML5 开始提供的一种浏览器与服务器进行全双工通讯的协议,属于应用层。它基于TCP传输协议,并复用HTTP的握手通道。

        也就是说,建立一个 WebSocket 连接,客户端浏览器首先要向服务器发起一个 HTTP 请求,这个请求和通常的 HTTP 请求不同,包含了一些附加头信息,其中附加头信息 "Upgrade: WebSocket" 表明这是一个申请将协议升级为WebSocket的 HTTP 请求(具体见图1),服务器端解析这些附加的头信息然后产生应答信息返回给客户端,客户端和服务器端的 WebSocket 连接就建立起来了,此时支持双向数据传输,这是一个长连接,会持续存在直到客户端或者服务器端的某一方主动的关闭连接。

 (图1,项目真实抓包)

方法及事件介绍

假设我们创建了一个 ws 对象:

var ws = new WebSocket(url, [protocol] );

参数说明:
    url:指定连接的 URL;
    protocol:可选,指定可接受的子协议。

ws 对象上的事件:

事件说明
open连接建立时触发
message客户端接收到服务端消息时触发
error通信出现错误时触发
close连接关闭时触发

另外,我们可以通过 ws.send() 方法,给服务端发送数据;也可以通过 ws.close() 方法主动断开连接。

用例代码

服务端代码

1. 初始化一个node项目

npm init -y

2. 新建一个入口文件 app.js,这里基于koa框架,需要先npm install koa,其他依赖根据提示缺少什么就安装什么,这里不拓展啦。

//app.js
// 使用koa
const koa = require('koa')
const router = require('koa-router')()
// koa-websocket是koa封装好的websocket功能
const websocket = require('koa-websocket')
// 实例化一个ws服务
const app = websocket(new koa())

// 监听koa/ws路由,是否有连接
router.all('/koa/ws', (ctx) => {
    // 监听客户端发送过来的信息
    ctx.websocket.on('message', function(message) {
        console.log('收到了客户端发过来的消息:' + message);
        // 向客户端发送消息
        ctx.websocket.send('我是服务端')
        console.log('已向客户端发送数据')
        
    });
})
// 使用路由
app.ws.use(router.routes()).use(router.allowedMethods())

//端口号后面可采用动态的
app.listen(3000, () =>
    console.log('服务启动成功')
)

3. 输入命令启动服务

node app.js

客户端代码

1. 新建一个test.html文件

// test.html
<!DOCTYPE html>
<html>
   <head>
   <meta charset="utf-8">
   <title>client</title>
    
    <script type="text/javascript">
        function WebSocketTest() {
            if ("WebSocket" in window){  //判断当前浏览器是否支持websocket
                alert("您的浏览器支持 WebSocket!");
                
                // 打开一个 web socket
                let ws = new WebSocket('ws://localhost:3000/koa/ws');
                // onopen是客户端与服务端建立连接后触发
                ws.onopen = function(){
                    // 使用 send() 方法发送数据
                    ws.send("我是客户端");
                    console.log('已向服务端发送数据')
                };
                //监听服务端发过来的信息
                ws.onmessage = function (msg) { 
                    var received_msg = msg.data;
                    console.log('收到了服务端发过来的信息:'+received_msg)
                };
                ws.onclose = function(){ 
                    // 关闭 websocket
                    alert("连接已关闭..."); 
                };
            }else{
                // 浏览器不支持 WebSocket
                alert("您的浏览器不支持 WebSocket!");
            }
        }
    </script>
   </head>
   <body>
   
      <div>
         <button onclick="WebSocketTest()">开启websocket连接</button>
      </div>
      
   </body>
</html>

2. 浏览器打开 test.html 文件

以上客户端/服务端代码执行效果概括为:点击 “开启websocket连接” 按钮,会触发WebSocketTest方法,即会建立一个websocket连接。

此时客户端的打印是:

服务端的打印是:

 

 由此可见,一个websocket连接已成功建立,双方可以通过send方法自由给对方发送数据。

最后

        WebSocket建立的是长连接,且允许服务端主动向客户端推送数据,使得客户端和服务器之间的数据交换变得更加简单。

相关文章:

  • 牛视源码定制,抖音矩阵系统,别和谐啊、、、
  • 深度神经网络的可解释性,深度神经网络简单介绍
  • (2022版)一套教程搞定k8s安装到实战 | RBAC
  • 海川QK1209 低压按键台灯充电 LED 驱动 IC- 昱灿电子
  • 受邀参加中日韩创新人才主题交流研讨会
  • 优炫软件董事长梁继良当选新一届北京市商会副会长
  • 5G与UWB定位技术融合的四种方式
  • 企业为什么难创新?5个常见的创新障碍
  • leetcode:762. 二进制表示中质数个计算置位
  • PASCAL VOC数据集格式文件夹下文件配置
  • Sulfo-Cy3 羧酸,Sulfo-Cy3 carboxylic acid,水溶性Cy3荧光染料标记羧酸
  • 银行笔试题 java笔试题
  • Apache Doris 系列: 入门篇-安装部署
  • 阿里P8MySQL,基础/索引/锁/日志/调优都不误,一锅深扒端给你
  • 虹科分享 | 简单实用的CANopen介绍,看完你就明白了(3)——对象字典、SDO、PDO
  • docker-consul
  • ECMAScript6(0):ES6简明参考手册
  • Java-详解HashMap
  • nodejs:开发并发布一个nodejs包
  • SpriteKit 技巧之添加背景图片
  • UMLCHINA 首席专家潘加宇鼎力推荐
  • unity如何实现一个固定宽度的orthagraphic相机
  • 半理解系列--Promise的进化史
  • 买一台 iPhone X,还是创建一家未来的独角兽?
  • 算法-图和图算法
  • 腾讯大梁:DevOps最后一棒,有效构建海量运营的持续反馈能力
  • 腾讯优测优分享 | Android碎片化问题小结——关于闪光灯的那些事儿
  • 协程
  • 一道闭包题引发的思考
  • 一个完整Java Web项目背后的密码
  • 鱼骨图 - 如何绘制?
  • 在Mac OS X上安装 Ruby运行环境
  • nb
  • gunicorn工作原理
  • 阿里云移动端播放器高级功能介绍
  • 教程:使用iPhone相机和openCV来完成3D重建(第一部分) ...
  • 浅谈sql中的in与not in,exists与not exists的区别
  • #etcd#安装时出错
  • #gStore-weekly | gStore最新版本1.0之三角形计数函数的使用
  • #Linux(make工具和makefile文件以及makefile语法)
  • #pragma pack(1)
  • (C语言)fgets与fputs函数详解
  • (Demo分享)利用原生JavaScript-随机数-实现做一个烟花案例
  • (done) ROC曲线 和 AUC值 分别是什么?
  • (JSP)EL——优化登录界面,获取对象,获取数据
  • (附源码)spring boot基于Java的电影院售票与管理系统毕业设计 011449
  • (转)linux下的时间函数使用
  • (轉貼) VS2005 快捷键 (初級) (.NET) (Visual Studio)
  • *ST京蓝入股力合节能 着力绿色智慧城市服务
  • .Net - 类的介绍
  • .NET Framework与.NET Framework SDK有什么不同?
  • .NET 材料检测系统崩溃分析
  • .Net 中Partitioner static与dynamic的性能对比
  • .NET:自动将请求参数绑定到ASPX、ASHX和MVC(菜鸟必看)
  • [ 蓝桥杯Web真题 ]-布局切换