什么是Socket.IO

Socket.IO是一个库,可用于在浏览器和服务器之间进行实时,双向和基于事件的通信。它包括:

  • 使Node.js服务器:来源 | API
  • 为浏览器(可从Node.js的也运行)一个JavaScript客户端库:来源 | API

其主要特点是:

可靠性

即使存在以下情况,也会建立连接:

  • 代理和负载平衡器。
  • 个人防火墙和防病毒软件。

为此,它依赖于Engine.IO,该引擎首先建立长轮询连接,然后尝试升级到在侧面进行“测试”的更好传输,例如WebSocket。请参阅“ 目标”部分以获取更多信息。

自动重新连接支持

除非另有指示,否则断开连接的客户端将尝试永久重新连接,直到服务器再次可用为止。请在此处查看可用的重新连接选项。

断线检测

心跳机制在Engine.IO级别上实现,使服务器和客户端都可以知道对方何时不再响应。

通过在服务器和客户端上设置计时器,并在连接握手期间共享超时值(pingInterval和pingTimeout参数),可以实现该功能。这些计时器要求将任何后续客户端调用都定向到同一服务器,因此使用多个节点时需要执行粘性会话。

二进制支持

可以发出任何可序列化的数据结构,包括:

  • 浏览器中的ArrayBuffer和Blob
  • Node.js中的ArrayBuffer和Buffer

多路传输支持

为了在应用程序内创建关注点分离(例如,每个模块或基于权限),Socket.IO允许您创建多个Namespaces,它们将充当单独的通信通道,但将共享相同的基础连接。

客房支援

在每个Namespace中,您可以定义套接字可以加入和离开的任意通道,称为Rooms。然后,您可以广播到任何给定的房间,到达已加入该房间的每个插槽。

这是有用的功能,用于向一组用户或连接到多个设备的给定用户发送通知。

这些功能附带一个简单便捷的API,如下所示:

io.on('connection',function(socket) { 
  socket.emit('request',/ * * /); //向套接字发出事件
   io.emit('broadcast',/ * * /); / /向所有连接的套接字发出事件
   socket.on('reply',function() { / * * / }); //监听事件
 }); 

什么不是Socket.IO

Socket.IO 不是 WebSocket实现。尽管Socket.IO确实确实在可能的情况下使用WebSocket作为传输工具,但它会向每个数据包添加一些元数据:当需要消息确认时,数据包类型,名称空间和数据包ID。这就是为什么WebSocket客户端将无法成功连接到Socket.IO服务器,而Socket.IO客户端也将无法连接到WebSocket服务器的原因。请在此处查看协议规范。

//警告:客户端将无法连接!
const client = io('ws://echo.websocket.org'); 

正在安装

服务器

npm install --save socket.io 

资源

Javascript客户端

默认情况下,服务器会公开客户端的独立版本/socket.io/socket.io.js

也可以从CDN提供服务,例如cdnjs。

若要从Node.js的使用就像一个捆绑使用,或的WebPack或browserify,您还可以安装NPM包:

npm install-save socket.io-client 

资源

其他客户端实施

有几种其他语言的客户端实现,由社区维护:

  • Java:https://github.com/socketio/socket.io-client-java
  • C ++:https://github.com/socketio/socket.io-client-cpp
  • 斯威夫特:https : //github.com/socketio/socket.io-client-swift
  • 飞镖:https://github.com/rikulo/socket.io-client-dart
  • Python:https://github.com/miguelgrinberg/python-socketio
  • .Net:https://github.com/Quobject/SocketIoClientDotNet

与Node http服务器一起使用

服务器(app.js)

var app = require('http').createServer(handler)
var io = require('socket.io')(app);
var fs = require('fs');

app.listen(80);

function handler (req, res) {
  fs.readFile(__dirname + '/index.html',
  function (err, data) {
    if (err) {
      res.writeHead(500);
      return res.end('Error loading index.html');
    }

    res.writeHead(200);
    res.end(data);
  });
}

io.on('connection', function (socket) {
  socket.emit('news', { hello: 'world' });
  socket.on('my other event', function (data) {
    console.log(data);
  });
}); 

客户端(index.html)

 



与Express一起使用

服务器(app.js)

var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);

server.listen(80);
// WARNING: app.listen(80) will NOT work here!

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

io.on('connection', function (socket) {
  socket.emit('news', { hello: 'world' });
  socket.on('my other event', function (data) {
    console.log(data);
  });
}); 

客户端(index.html)

 



发送和接收事件

Socket.IO允许您发射和接收自定义事件。此外connectmessagedisconnect,你可以发出自定义事件:

服务器

// note, io() will create a http server for you
var io = require('socket.io')(80);

io.on('connection', function (socket) {
  io.emit('this', { will: 'be received by everyone'});

  socket.on('private message', function (from, msg) {
    console.log('I received a private message by ', from, ' saying ', msg);
  });

  socket.on('disconnect', function () {
    io.emit('user disconnected');
  });
}); 

将自己限制为名称空间

如果您可以控制为特定应用程序发出的所有消息和事件,则可以使用默认值/命名空间。如果您想利用第三方代码或生成与他人共享的代码,socket.io提供了一种命名套接字的方式。

这具有multiplexing单个连接的优点。不是使用两个WebSocket连接,而是使用一个连接。

服务器(app.js)

var io = require('socket.io')(80);
var chat = io
  .of('/chat')
  .on('connection', function (socket) {
    socket.emit('a message', {
        that: 'only'
      , '/chat': 'will get'
    });
    chat.emit('a message', {
        everyone: 'in'
      , '/chat': 'will get'
    });
  });

var news = io
  .of('/news')
  .on('connection', function (socket) {
    socket.emit('item', { news: 'item' });
  }); 

客户端(index.html)

 

发送易失性消息

有时可能会丢弃某些消息。假设您有一个应用程序可显示关键字的实时推文bieber

如果某个客户端尚未准备好接收消息(由于网络速度慢或其他问题,或者由于它们是通过长时间轮询连接的,并且处于请求-响应周期的中间),则它没有接收到所有推文与bieber相关,您的应用程序不会受到影响。

在这种情况下,您可能希望将这些消息作为易失性消息发送。

服务器

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

io.on('connection', function (socket) {
  var tweets = setInterval(function () {
    getBieberTweet(function (tweet) {
      socket.volatile.emit('bieber tweet', tweet);
    });
  }, 100);

  socket.on('disconnect', function () {
    clearInterval(tweets);
  });
}); 

发送和获取数据(确认)

有时,当客户端确认消息接收后,您可能希望获得回调。

为此,只需将函数作为.send或的最后一个参数传递即可.emit。而且,当您使用时.emit,确认是由您完成的,这意味着您还可以传递数据:

服务器(app.js)

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

io.on('connection', function (socket) {
  socket.on('ferret', function (name, word, fn) {
    fn(name + ' says ' + word);
  });
}); 

客户端(index.html)

 

广播消息

要广播,只需broadcastemitsend方法调用中添加一个标志。广播意味着将消息发送到其他人(除了启动该消息的套接字之外)。

服务器

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

io.on('connection', function (socket) {
  socket.broadcast.emit('user connected');
}); 

像跨浏览器的WebSocket一样使用它

如果只需要WebSocket语义,也可以这样做。只需利用send并收听message事件:

服务器(app.js)

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

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

客户端(index.html)

 

如果您不关心此类的重新连接逻辑,请查看Engine.IO,这是Socket.IO使用的WebSocket语义传输层。

标签:Socketio

Socket.IO基础教程的更多相关文章

  1. 使用nodejs和express搭建http web服务

    目录简介使用nodejs搭建HTTP web服务请求nodejs服务第三方lib请求post获取http请求的正文E......

  2. 在nodejs中创建child process

    目录简介child process异步创建进程同步创建进程在nodejs中创建child process简介node......

  3. 在使用内模块的时候需要先将所需的内置模块进行引入、OS模块在nodejs中OS模块提供了与操作系统相关的属性和方法/......

  4. node.js常用内置模块一

    在使用内模块的时候需要先将所需的内置模块进行引入、OS模块在nodejs中OS模块提供了与操作系统相关的属性和方法/......

  5. nodejs事件和事件循环详解

    目录简介nodejs中的事件循环phase详解timerspending callbacksidle, prepar......

  6. Socket.IO基础教程

    什么是Socket.IOSocket.IO是一个库,可用于在浏览器和服务器之间进行实时,双向和基于事件的通信。它包括......

  7. pixi.js 自定义光标样式

    pixi 介绍Pixi是一个超快的2D渲染引擎,通过Javascript和Html技术创建动画或管理交互式图像,从而......

  8. JS实现公告上线滚动效果

    本文实例为大家分享了JS实现公告上线滚动效果的具体代码,供大家参考,具体内容如下实现的效果如下,新闻公告上下滚动。代......

  9. nodejs中的文件系统

    、目录简介nodejs中的文件系统模块Promise版本的fs文件描述符fs.stat文件状态信息fs的文件读写fs......

随机推荐

  1. 用python批量移动文件

    我是用来移动图片的,其他格式的文档也是可以的,改下后缀列表就可以了import os,shutilimport da......

  2. C# 合并和拆分PDF文件

    一、合并和拆分PDF文件的方式 PDF文件使用了工业标准的压缩算法,易于传输与储存。它还是页独立的,一个PDF文件包......

  3. 用Python自动清理电脑内重复文件,只要10行代码(自动脚本)

    给定一个文件夹,使用Python检查给定文件夹下有无文件重复,若存在重复则删除主要涉及的知识点有:os模块综合应用g......

  4. C#微信公众号推送消息接口消息排重

    用户在微信公众号发送文本,语音,图片等的普通消息时,微信服务器会向公众号配置的接收消息的地址转发用户消息,微信服务器......

  5. javascript中call,apply,bind的区别详解

    在JS中,这三者都是用来改变函数的this对象的指向的,他们有什么样的区别呢。在说区别之前还是先总结一下三者的相似之......

  6. 浅入 .NET Core 中的内存和GC知识

    目录 托管代码 自动内存管理 参考资料: 【1】https://docs.microsoft.com/z......

  7. 利用python绘制正态分布曲线

    使用Python绘制正态分布曲线,借助matplotlib绘图工具;#-*-coding:utf-8-*-"......

  8. python pillow库的基础使用教程

    知识点图像模块 (Image.Image)Image模块的功能Image模块的方法ImageChops模块Image......

  9. ASP.NET Core 3.1 中间件

    参考微软官方文档 :https://docs.microsoft.com/zh-cn/aspnet/core/fun......

  10. JS removeAttribute()方法实现删除元素的某个属性

    在 JavaScript 中,使用元素的 removeAttribute() 方法可以删除指定的属性。用法如下:re......