实时通讯之Socket.io

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
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是一个使用Socket.IO在Node.js中实现通讯的示例代码: 1. 安装Socket.IO模块: ```shell npm install socket.io ``` 2. 创建服务器端(server.js): ```javascript var express = require('express'); var app = express(); var server = require('http').createServer(app); var io = require('socket.io')(server); // 监听客户端连接事件 io.on('connection', function(socket){ console.log('A client connected.'); // 监听客户端发送的消息事件 socket.on('message', function(data){ console.log('Received message from client:', data); // 触发事件告知客户端 io.emit('message', 'Server received your message: ' + data); }); // 监听客户端离开事件 socket.on('disconnect', function(){ console.log('A client disconnected.'); // 触发事件告知服务端 io.emit('disconnect', 'A client disconnected.'); }); }); // 启动服务器 server.listen(3000, function(){ console.log('Server is running on port 3000.'); }); ``` 3. 创建客户端(client.html): ```html <!DOCTYPE html> <html> <head> <title>Socket.IO Client</title> <script src="https://cdn.socket.io/socket.io-3.1.3.min.js"></script> <script> var socket = io(); // 发送消息给服务端 socket.emit('message', 'Hello, server!'); // 监听服务端发送的消息事件 socket.on('message', function(data){ console.log('Received message from server:', data); }); // 监听服务端触发的离开事件 socket.on('disconnect', function(data){ console.log('Server:', data); }); </script> </head> <body> <h1>Socket.IO Client</h1> </body> </html> ``` 请注意,以上代码仅为示例,实际使用时可能需要根据具体需求进行修改。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值