首页 > 其他分享 >#yyds干货盘点#详细讲讲WebSocke

#yyds干货盘点#详细讲讲WebSocke

时间:2023-04-16 15:32:57浏览次数:42  
标签:function yyds socket 干货 io WebSocke 连接 服务端 客户端

WebSocket

WebSocketHTML5开始提供的一种浏览器与服务器间进行全双工通讯的网络技术。

现很多网站为了实现即时通讯,所用的技术都是轮询(polling)轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客服端的浏览器,这种方式有一个很大的弊端,就是会占用很多的带宽

最新的轮询效果是Comet – 用了AJAX。但这种技术虽然可达到全双工通信,但依然需要发出请求。

使用WebSocket,浏览器和服务器只需要要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道,两者之间就直接可以数据互相传送。而且它为我们实现即时服务带来了两大好处:

节省资源:互相沟通的Header是很小的-大概只有 2 Bytes
推送信息:不需要客户端请求,服务器可以主动传送数据给客户端

socket.io

Socket.IO是一个WebSocket库,包括了客户端的js和服务器端的nodejs,它的目标是构建可以在不同浏览器和移动设备上使用的实时应用

socket.io的特点

  • 易用性socket.io封装了服务端和客户端,使用起来非常简单方便。
  • 跨平台socket.io支持跨平台,这就意味着你有了更多的选择,可以在自己喜欢的平台下开发实时应用。
  • 自适应:它会自动根据浏览器从WebSocketAJAX长轮询Iframe流等等各种方式中选择最佳的方式来实现网络实时应用,非常方便和人性化,而且支持的浏览器最低达IE5.5。

安装部署

npm install socket.io

服务监听

socket.io的服务端启动非常的简单,引用socket.io模块

var io = require('socket.io');

然后调用listen函数,传入监听的端口号,开始服务监听。启用了80端口用于测试:

var io = require('socket.io')(80);

注册事件

io.on('connection', function (socket) {
    socket.on('disconnect', function () {

    })
})

connection事件在客户端成功连接到服务端时触发,有了这个事件,我们可以随时掌握用户连接到服务端的信息。

当客户端成功建立连接时,在connection事件的回调函数中,我们还是可以为socket注册一些常用的事件,如:disconnect事件,它在客户端连接断开是触发,这时候我就知道用户已经离开了。


启动服务

目前为止,我们已经搭建好了一个最简单的socket服务器,为了在浏览器中能够访问到我们的服务,我们还需要在服务端搭建一个简单的web服务器,让浏览器能够访问我们的客户端页面。

为了便捷,我们选用node.js中常用的express框架来实现web服务,示例如下:

var express = require('express');
var app = express();
app.get('/', function (req, res) {
    res.status(200).send('成功连接!')
});
var server = require('http').createServer(app);
var io = require('socket.io')(server);
io.on('connection', function (socket) {

});
server.listen(80);

客户端引用

服务端构建完毕,下面看一看客户端应该如何使用。

服务端运行后会在根目录动态生成socket.io的客户端js文件,客户端可以通过固定路径/socket.io/socket.io.js添加引用。

首先添加网页index.html,并在网页中引用客户端js文件:

<script src="//cdn.bootcss.com/socket.io/2.0.2/socket.io.js"></script>

连接服务

当客户端成功加载socket.io客户端文件后会获取到一个全局对象io,我们将通过io.connect函数来向服务端发起连接请求。

var socket = io.connect('/');
socket.on('connect',function(){
    //连接成功
});
socket.on('disconnect',function(data){
    //连接断开
});

connect函数可以接受一个url参数,url可以socket服务的http完整地址,也可以是相对路径,如果省略则表示默认连接当前路径。与服务端类似,客户端也需要注册相应的事件来捕获信息,不同的是客户端连接成功的事件是connect

了解了客户端如何使用,下面我们创建网页index.html,并添加如下内容(保存):

<html>
<head>
    <script src="//cdn.bootcss.com/socket.io/2.0.2/socket.io.js"></script>
    <script>
        window.onload = function(){
            var socket = io.connect('/');
            socket.on('connect',function(){
                document.write('连接成功!');
            });
        };
    </script>
</head>
<body>
</body>
</html>

页面添加完毕还要记得在服务端app.js中为它添加路由,让我们可以访问测试网页:

app.get('/index',function(req,res){
   res.sendFile('index.html',{root:__dirname});
});

实时通讯

服务端和客户端都构建完毕了,下面开始发送消息。

当我们成功建立连接后,我们可以通过socket对象send函数来互相发送消息,示例-客户端向服务端发送消息(index.html):

var socket = io.connect('/');
socket.on('connect',function(){
   //客户端连接成功后发送消息'hello world!'
   socket.send('hello world!');
});
socket.on('message',function(data){
   alert(data);
});

连接成功后,我们向服务端发送消息hello world!,还为socket注册了message事件,它是send函数对应的接收消息的事件,当服务端向客户端send消息时,我们就可以在message事件中接收到发送过来的消息。

服务端向客户端发送消息也可以通过send的方式,示例 - 服务端向客户端发送消息(app.js):

var io = require('scoket.io');
io.on('connection', function (socket) {
    socket.send('Hello World!');
    socket.on('message', function (data) {
        console.log(data);
    })
});

与客户端相同,服务端也需要为socket注册message事件来接收客户端发送过来的消息。

发送信息

socket.io既然是用来实现通讯的,那么如何发送、接收信息才是根本。

socket.io中,emit函数用于发送数据,我们使用send的方式实现了信息的互发,其实send函数只是emit的封装,实际上还是使用了emit,且看send函数是如何实现的:

function send(){
  var args = toArray(arguments);
  args.unshift('message');
  this.emit.apply(this, args);
  return this;
}

send函数中,获取到原来的参数,并在原来的基础上插入了一个参数message,然后调用了emit函数。通过send函数的实现,我们也学会了emit函数的用法,它有多个参数,第一个参数是事件名称,在接收端注册该事件就可以接收到发送过去的信息,事件名称可以自由定义,在不同的场景下,我们可以定义不同的事件来接收消息。第二个参数才是发送的数据。了解清楚了工作原理,下面来将send替换成emit函数发送信息:

//app.js
io.on('connection',function(socket){
     socket.emit('message','连接成功!');
     socket.on('message',function(data){
    });
});

服务端事件

事件监听是实现通讯的基础,因此充分了解socket.io的事件,学习如何在正确的时候使用它们至关重要。在一些关键的的状态下,socket.io可以注册相应的事件,通过事件监听,我们可以在这些事件中作出反应,常用的事件如下:

  • connection——客户端成功连接到服务器。
  • message——捕获客户端send信息。。
  • disconnect——客户端断开连接。
  • error——发生错误。

客户端

较服务端而言,客户端提供更多的监听事件,在实时应用中,我们可以为这些事件注册监听并作出反应,例如:connect提示用户连接成功,disconnect时提示用户停止服务等等。

  • connection——成功连接到服务器。
  • connecting——正在连接。
  • disconnect——断开连接。
  • connect_failed——连接失败。
  • error——连接错误。
  • message——监听服务端send的信息。
  • reconnect_failed——重新连接失败。
  • reconnect——重新连接成功。
  • reconnecting——正在重连。

那么客户端socket发起连接时的顺序是怎么样的呢?当第一次连接时,事件触发顺序为: connecting → connect

当失去连接时,事件触发顺序为:disconnect → reconnecting → connecting → reconnect → connect

命名空间

命名空间着实是一个非常实用好用的功能。我们可以通过命名空间,划分出不同的房间,在房间里的广播和通信都不会影响到房间以外的客户端。

那么如何创建房间呢?在服务端,通过of("")的方式来划分新的命名空间:

io.of('chat').on('connection',function(socket){
});

示例中,我们创建一个名为chat的房间,客户端可以通过如下方式连接到指定的房间:

var socket = io.connect('/chat');

虽然连接到指定的房间,但是我们也可以在服务端操作,自由的进出房间:

socket.join('chat');//进入chat房间
socket.leave('chat');//离开chat房间

广播消息

在实时应用中,广播是一个不可或缺的功能,socket.io提供两种服务端广播方式。

第一种广播方式可以称之为'全局广播',顾名思义,全局广播就是所有连接到服务器的客户端都会受到广播的信息:

socket.broadcast.emit('DATA',data);

但是,在实际应用场景中,我们很多时候并不需要所有用户都收到广播信息,有的广播信息只发送给一部分客户端,比如某个房间里面的用户,那么可以使用如下方式:

socket.broadcast.to('chat').emit('DATA',data);

中间件

socket.io提供中间件功能,我们可以通过中间件来对请求进行预处理,比如身份验证:

io.use(function(socket, next){
  if (socket.request.headers.cookie) return next();
  next(new Error('Authentication error'));
});

示例中展示了通过中间件进行身份验证,当没有cookie的时候抛出异常。

传递参数

在很多应用场景中,客户端发起连接请求时都需要传递参数,这些参数可能是身份验证、初始化设置等等,那么socket.io发起连接时如何传递参数呢?

var socket = io.connect('/');

由于connect函数发起连接的参数是一个url,你可能会想到把参数拼接到url上,如http://xxxx?xx=xxxx,但是很遗憾这样是行不通的,我们可以通过这样的方式来传递参数:

var socket = io.connect('/',{ _query:'sid=123456' });

在服务端可以这样获取到传递的参数:

io.use(function(socket){
     var query = socket.request._query;
     var sid = query.sid; 
});

客户端传递的参数已经被解析成了一个json对象,这个对象就是_query

标签:function,yyds,socket,干货,io,WebSocke,连接,服务端,客户端
From: https://blog.51cto.com/u_11365839/6193471

相关文章

  • WebSocket容量规划核对表与框架性测测试
    WebSocket连接     WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket通信协议于2011年被IETF定为标准RFC6455,并由RFC7936补充规范。WebSocketAPI也被W3C定为标准。WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。......
  • 华为手表开发:WATCH 3 Pro(13)websocket 请求数据到服务器
    华为手表开发:WATCH3Pro(13)websocket请求数据到服务器初环境与设备文件夹:文件重点核心代码:app.js新增一个文本输入框index.hmlindex.cssindex.js初希望能写一些简单的教程和案例分享给需要的人鸿蒙可穿戴开发环境与设备系统:window设备:HUAWEIWATCH3Pro开发工具:DevEcoStudio3......
  • #yyds干货盘点#MariaDB服务
    相较于MySQL,MariaDB数据库管理系统有了很多新鲜的扩展特性,例如对微秒级别的支持、线程池、子查询优化、进程报告等。在配置妥当Yum软件仓库后,即可安装部署MariaDB数据库主程序及服务端程序了。在确认MariaDB数据库软件程序安装完毕并成功启动后请不要立即使用。为了确保数据库的......
  • #yyds干货盘点#Spring事务回滚的两种方法
    Spring事务回滚的前提是你当前使用的数据库必须支持事务,比如MySQL的Innodb是支持的,但Mysaim则是不支持事务的。方法一使用@Transaction来配置自动回滚,可以配置在类上,也可以配置在方法上(作用域不同),但对final或private修饰的方法无效,且该类必须是受spring所管控的,也就是被已经被注......
  • #yyds干货盘点#dB、dBm、dBi、dBc,一文带你学习无线信号强度指标
    定义与由来dB是一个比值,是一个纯计数方法,没有任何单位标注,那它具有什么存在的意义呢。在无线通信里,常常用它来衡量一个地点的信号质量强度。为了纪念贝尔,所以采用贝尔的名字来对信号的衰减或增强进行命名,其表示为Bel=Log(输入信号的功率/输出信号的功率),在实际使用中这个单位太大,所......
  • #yyds干货盘点#Linux之find:查找目录下的文件
    【功能说明】find命令用于查找目录下的文件,同时也可以调用其他命令执行相应的操作。【语法格式】find[-H][-L][-P][-Ddebugopts][-olevel][pathname][expression]find[选项][路径][操作语句]1)注意find命令以及后面的选项和路径、操作语句,每个......
  • #yyds干货盘点# LeetCode程序员面试金典:K 个一组翻转链表
    题目:给你链表的头节点head,每 k 个节点一组进行翻转,请你返回修改后的链表。k是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。 示例1:输入:head=[1,......
  • #yyds干货盘点# LeetCode面试题:最小覆盖子串
    1.简述:给你一个字符串s、一个字符串t。返回s中涵盖t所有字符的最小子串。如果s中不存在涵盖t所有字符的子串,则返回空字符串""。 注意:对于t中重复字符,我们寻找的子字符串中该字符数量必须不少于t中该字符数量。如果s中存在这样的子串,我们保证它是唯一的答案。......
  • 干货 | 自动驾驶领域各大顶会顶刊集合梳理(附名单) 曼孚科技
    自动驾驶是近年来备受关注的热门领域之一,无论是Google、特斯拉、百度等知名企业,还是各大学术机构,都在积极探索自动驾驶的技术与应用。为了促进该领域的交流与发展,一些重要的顶级会议和期刊应运而生。这些国际学术会议与期刊不仅为自动驾驶技术的研究提供了平台,同时也为企业和机构......
  • WebSocket 一些简单地记录
    WebSocket是HTML5开始提供的一种在单个TCP连接上进行全双工通讯的协议。全双工(FullDuplex)是通讯传输的一个术语。通信允许数据在两个方向上同时传输,它在能力上相当于两个单工通信方式的结合。单工就是在只允许甲方向乙方传送信息,而乙方不能向甲方传送半双工(H......