Sockets.IO 实现一个简易聊天系统

在介绍 Socket.io 之前,首先需要说一说什么是 WebSocket。

什么是WebSocket?

WebSocket是一种让客户端和服务器之间进行双向实时通讯的技术,也是HTML5的的一个规范协议,本质是基于TCP协议,它通过http/https发送一条特殊的请求进行握手建立一个TCP连接,此后客户端和服务器之间便可以通过次连接进行双向通讯。


为什么要用WebSocket?

一直以来,http是无状态,单向通讯的,即客户端请求一次,服务器回复一次。如果想让服务器消息及时下发到客户端,需要采用类似于轮询的机制,下面介绍两种常见方式:

  • ajax 轮询

ajax轮询的原理很简单,就是让浏览器(客户端)定时(隔几秒)向服务器发送一次请求,浏览器就收服务器返 回的数据更新显示出来,然后重复这一过程:


  • Long Polling

Long Polling与ajax轮询的原理差不多,不过它算是polling的一种改进。客户端发送请求到服务器,服务端并不立即响应返回客户端,而是保持这次连接,当有新的数据时候,在返回客户端展示,并重复该过程。如果服务器长时间没有数据更新,这个请求会超时并且客户端收到消息后,重新发送新的请求。
从上面可以看出,两种方式的弊端是不断发送http请求,然后等服务器的处理。

ajax轮询方式-假如服务器短时间没有数据更新,客户端仍定时发送请求,服务器仍然发送老数据,这样做既浪费宽带又浪费CPU的占有率。

Long Polling方式一定程度上解决了宽带浪费和CPU占有率的情况,但是如果服务器的数据更新过快,服务器在返回一次数据给客户端之后,只能等客户端再发送一次请求之后,才能发送下一个数据包给客户端,如果再网络拥塞的情况下,这种情况是很多人不能接受的。


再这样的情况下,一种新的网络协议,可以支持客户端和服务端双向通讯的协议 WebSocket 因应而生了。

WebSocket协议

WebSocket 协议是一种持久化的双向通信协议,它建立在TCP之上,同 HTTP 一样通过 TCP 来传输数据,但是它和 HTTP 最大的不同点有

  • 服务端可以主动向客户端推送数据,客户端也可以主动向服务器推送数据
  • 服务器与客户端之间建立一个非http的双向通道。这个通道是实时的,也是永久的(除非被关闭)



WebSocket与http、tcp的关系

WebSocket在建立握手连接时,请求体是通过http协议传输的,连接成功后真正的数据传输是不需要http协议参与的。


WebSocket API

WebSocket对象作为一个构造函数,通过new WebSocket('ws://xxxx.com') 客户端会与服务器进行连接 。


浏览器支持

WebSocket是HTML5新提出的规范,从上面得知虽然主流的浏览器都已经支持,但如果低版本或部分浏览器仍存在兼容问题。
为了兼容所有浏览器,提供统一的编程写法。SocketIO将WebSocket、AJAX和其他通讯方式全部封装成统一通讯接口。也就是说,我们在使用SocketIO时候,不在考虑担心兼容问题,底层会自动选用最佳通讯方式,因此说Web是SocketIO的子集。


Socket.io 介绍

SocketIO是一个完全由JavaScript实现、基于Node.js、支持WebSocket协议用于实时通讯、跨平台、解决众多浏览器兼容开源库,包括客户端JavaScript和服务器的Node.js

Socket.io支持的通讯方式

  • WebSocket
  • Adobe Flash Socket
  • AJAX long-polling
  • AJAX multipart streaming
  • Forever IFrame
  • JSONP polling

Socket.io的使用

服务端可以使用node.js express框架搭建

引入

服务端:
npm install --save socket.io

浏览器端(CDN加速):

cdnjs: https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.1.2/socket.io.min.js

vue:

npm install vue-socket.io --save


Socket实例(服务端)

安装 Socket.IO之后,现在就可以初始化服务器了。选项的完整列表可以在下面找到

通过上面两种方式导入并初始化IO,参数 httpServer 是要绑定的服务器,options 是初始化的一些配置,常用配置如下:

path

默认值:/socket.io/

描述:服务器端捕获的路径的名称,同时服务器和客户端值必须匹配

pingTimeout

默认值:20000ms

描述:此值用于心跳机制,该机制定期检查服务器和客户端之间的连接是否仍然存在,服务器发送一个 ping,如果客户机在pingTimeout ms 中没发送pong应答,服务器将认为连接已关闭。

pingInterval

默认值:25000ms

描述:类似地,如果客户机在 pingInterval + pingTimeout ms 内没有从服务器接收 ping,那么客户机也会认为连接已经关闭

maxHttpBufferSize

默认值:1e6 (1 MB)

描述:单个消息可以有多少个字节。您可以根据自己的需要增加或减少这个值。

transports

默认值:["polling", "websocket"]

描述:首先使用 HTTP建立长轮询连接,然后尝试升级到 WebSocket

cors

默认值:-

描述:将转发到 origin 模块的选项列表,更多信息https://www.npmjs.com/package/cors


socket.io事件(服务端)

Socket实例提供了默认事件(如:connection, disconnect)。另外,Socket.IO允许发送并接收自定义事件。

  • 监听客户端连接,回调函数会传递本次连接的socke
  • 监听客户端断开,回调函数参数是断开的原因
  • 给所有客户端广播消息,eventName客户端监听注册事件,data返回数据

       

  • 给指定的客户端发送自定义事件

  • 接收客户端发送的自定义事件

 


房间(room)

房间是 Socket.IO 提供的一个非常好用的功能。房间相当于为指定的一些客户端提供了一个命名空间,所有在房间里的广播和通信都不会影响到房间以外的客户端。

  • 使用 join() 方法将 socket 加入房间
  • 使用 leave() 方法离开房间:
  • 向房间中除了当前 socket 的其他 socket 发送消息
  • 向房间中所有的 socket 发送消息

命名空间

通过命名空间 of() 可以为 Socket.IO 设置子程序。默认命名空间为 “/”,Socket.IO 默认连接该路径。通过路径名(例如:/chat)标识的给定范围下连接的套接字池,且各个路径下的连接池不干扰。


Socket实例(客户端)

如果你的前端服务器和你的服务器在同一个域名,你可以简单地使用:

建立有命名空间的 socket 连接

监听服务器消息

向服务器发送消息

监听 socket 断开与重连事件


注:如果你使用Node.js做服务端,那么毫无疑问你该选择Socket.IO,它本省就是从Node.js开始的,但如果是使用Java做服务端,同时又恰好使用Spring Framework作为框架,那么推荐使用SockJS+Stomp

简单聊天室

流程:

  • 创建socket服务器
  • 浏览器建立socket连接
  • 进入首页随机生成头像,输入用户名和房间号进入房间
  • 发送数据与房间内好友聊天
  • 支持数据发送,文本、图片和视频

node端代码

浏览器 socket 代码


socket.ioAPI文档参考: https://socket.io/
查看api兼容性参考:https://www.caniuse.com/

深入了解websocket: https://www.zhihu.com/question/20215561

项目git 连接:https://github.com/Arrizo/sockets

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值