WebSocket
WebSocket是HTML5开始提供的一种浏览器与服务器间进行全双工通讯的网络技术。使用WebSocket,浏览器和服务器只需要要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道,两者之间就直接可以数据互相传送。而且它为我们实现即时服务带来了两大好处:
- 节省资源:互相沟通的Header是很小的-大概只有 2 Bytes。
- 推送信息:不需要客户端请求,服务器可以主动传送数据给客户端。
socket.io
Socket.IO是一个WebSocket库,包括了客户端的js和服务器端的nodejs,它的目标是构建可以在不同浏览器和移动设备上使用的实时应用。
服务监听
socket.io的服务端启动非常的简单,引用socket.io模块。然后调用listen函数,传入监听的端口号,开始服务监听。
var io
=
require('socket.io')(80);
注册事件
connection事件在客户端成功连接到服务端时触发,有了这个事件,我们可以随时掌握用户连接到服务端的信息。
当客户端成功建立连接时,在connection事件的回调函数中,我们还是可以为socket注册一些常用的事件,如:disconnect事件,它在客户端连接断开是触发,这时候我就知道用户已经离开了。
var io
=
require('socket.io')(80);
io.on('connection',function(socket){
//连接成功...
socket.on('disconnect',function(){
//用户已经离开...
});
});
启动服务
为了在浏览器中能够访问到我们的服务,我们还需要在服务端搭建一个简单的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="/socket.io/socket.io.js"></script>
当然这样的客户端引用方式并不是必须的,我们也可以引用官方的cdn或者下载到本地的客户端文件。一般情况下推荐引用动态生成的客户端文件,因为这样客户端和服务端的版本可以保持一致,减少出错的几率。
<script src="https://cdn.socket.io/socket.io-1.2.1.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。
实时通讯
当我们成功建立连接后,我们可以通过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('欢迎!');
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可以注册相应的事件,通过事件监听,我们可以在这些事件中作出反应,常用的事件如下:
connection |
客户端成功连接到服务器。 |
message |
捕获客户端send信息。 |
disconnect |
客户端断开连接。 |
error |
发生错误。 |
客户端事件
较服务端而言,客户端提供更多的监听事件,在实时应用中,我们可以为这些事件注册监听并作出反应。
connect |
成功连接到服务器。 |
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);
当使用to()的方式广播信息时,只有该命名空间下的客户端才会收到广播信息,是不是很方便呢。
传递参数
在很多应用场景中,客户端发起连接请求时都需要传递参数,这些参数可能是身份验证、初始化设置等等,那么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。
http://cnodejs.org/topic/50a1fcc7637ffa4155b5a264 socket.io入门整理
- 一个关于vue+mysql+express的全栈项目(五)------ 实时聊天部分socket.io
一.基于web端的实时通讯,我们都知道有websocket,为了快速开发,本项目我们采用socket.io(客户端使用socket.io-client) Socket.io是一个WebSocket库, ...
- Win10环境下使用Flask配合Celery异步推送实时/定时消息(Socket.io)/2020年最新攻略
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_163 首先得明确一点,和Django一样,在2020年Flask 1.1.1以后的版本都不需要所谓的三方库支持,即Flask-Ce ...
- html5的新通讯技术socket.io,实现一个聊天室
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Socket.IO – 基于 WebSocket 构建跨浏览器的实时应用
Socket.IO 是一个功能非常强大的框架,能够帮助你构建基于 WebSocket 的跨浏览器的实时应用.支持主流浏览器,多种平台,多种传输模式,还可以集合 Exppress 框架构建各种功能复杂 ...
- node.js+socket.io安装
最近做安卓遇到一个网络包的bug,服务端使用node做的,通讯用socket.io,但是服务端没法调试,没办法,还是自己搭建一个服务器端吧,索性买了阿里云的ecs测试,之前也配置过node+socke ...
- vue.js+socket.io+express+mongodb打造在线聊天
vue.js+socket.io+express+mongodb打造在线聊天 在线地址观看 http://www.chenleiming.com github地址 https://github.com ...
- vue.js+socket.io+express+mongodb打造在线聊天[二]
vue.js+socket.io+express+mongodb打造在线聊天[二] 在线地址观看 http://www.chenleiming.com github地址 https://github. ...
- Node.js精进(11)——Socket.IO
Socket.IO 是一个建立在 WebSocket 协议之上的库,可以在客户端和服务器之间实现低延迟.双向和基于事件的通信. 并且提供额外的保证,例如回退到 HTTP 长轮询.自动重连.数据包缓冲. ...
- 使用Node.js+Socket.IO搭建WebSocket实时应用
Web领域的实时推送技术,也被称作Realtime技术.这种技术要达到的目的是让用户不需要刷新浏览器就可以获得实时更新.它有着广泛的应用场景,比如在线聊天室.在线客服系统.评论系统.WebIM等. W ...
随机推荐
- [RN] React Native FlatList 选中后 状态没有立即发生改变,而在下一次生效的问题
React Native FlatList 选中后 状态没有立即发生改变,而在下一次生效的问题 解决关键: 给 FlatList 添加 extraData={this.state} 非常关键,如果不设 ...
- 支持TV远程控制的WIN10PEX64_17763网络版by双心
支持TV远程控制的WIN10PEX64_17763网络版by双心 用slore大神的wimbuilder2,基于cn_windows_10_enterprise_ltsc_2019_x64_dvd_9 ...
- Linux性能优化实战学习笔记:第五十一讲
一.上节回顾 上一节,我带你一起学习了常见的动态追踪方法.所谓动态追踪,就是在系统或者应用程序正常运行的时候,通过内核中提供的探针,来动态追踪它们的行为,从而辅助排查出性能问题的瓶颈. 使用动态追踪, ...
- BBS_02day
目录 BBS_02day: 展示个人所有文章: 点赞,点彩功能: 评论功能: BBS_02day: 展示个人所有文章: def article_detail(request,username,arti ...
- 热情组——项目冲刺 Day3
项目相关 作业相关 具体描述 班级 班级链接 作业要求 链接地址 团队名称 热情组 作业目标 实现软件制作,以及在福大的传播 Github链接 链接地址 SCRUM部分: 成员昵称 昨日目标 开始时间 ...
- 搭建Jena Fuseki并执行SPARQL查询
1. 下载Jena Fuseki:http://jena.apache.org/download/index.cgi 2. 运行服务 windows解压后双击fuseki-server.bat lin ...
- ApplicationInsights的探测器尝鲜
通常我们可以依靠ApplicationInsights(以下简称ai)来收集比如请求(request),依赖项(dependencies),异常(exception)等信息,但是无法收集到比如一个方法 ...
- SpringBoot第七篇:整合Mybatis-Plus
作者:追梦1819 原文:https://www.cnblogs.com/yanfei1819/p/10881666.html 版权声明:本文为博主原创文章,转载请附上博文链接! 引言 一看这个名 ...
- PHP curl cookie不识别
PHP curl cookie不识别 所以curl的时候别用setcookie 用了也没用
- Https通信原理及Android中实用总结
一.背景 Http俨然已经成为互联网上最广泛使用的应用层协议,随着应用形态的不断演进,传统的Http在安全性上开始面临挑战,Http主要安全问题体现在: 1,信息内容透明传输. 2,通信对方的身份不可 ...