前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >低延迟双向实时事件通信 Socket.IO

低延迟双向实时事件通信 Socket.IO

作者头像
Tinywan
发布2024-08-27 20:03:40
1360
发布2024-08-27 20:03:40
举报
文章被收录于专栏:开源技术小栈

什么是 Socket.IO

Socket.IO 是一个库,可以在客户端和服务器之间实现低延迟,双向基于事件的通信。

官网:https://socket.io

版本差异

Socket.IO自诞生以来经历了多个版本的迭代,主要版本有1.x、2.x和3.x。每个版本都带来了新特性和性能改进。

  • 1.x版本:这是Socket.IO的初始版本,奠定了基础架构。提供了基本的实时通信功能。
  • 2.x版本:引入了许多新特性,比如更好的错误处理机制、改进的协议、更加稳定的连接管理等。
  • 3.x版本:带来了更高的性能和更低的延迟。它还增强了对TypeScript的支持,并优化了与其他框架的集成。
  • 4.x版本:基于WebSocket的通信协议已更新,以支持HTTP/2。客户端和服务器之间的通信协议有所简化。服务器和客户端都已更新以使用更现代的JavaScript。服务器API有重大更改,以提高灵活性和简化配置。移除了对Node.js的旧版本支持。

语言实现

服务器实现

语言

网站

JavaScript (Node.js)

https://github.com/socketio/socket.io

JavaScript (Deno)

https://github.com/socketio/socket.io-deno

Java

https://github.com/mrniko/netty-socketio

Java

https://github.com/trinopoty/socket.io-server-java

Python

https://github.com/miguelgrinberg/python-socketio

Golang

https://github.com/googollee/go-socket.io

Rust

https://github.com/Totodore/socketioxide

PHP

https://github.com/walkor/phpsocket.io

客户端实现

语言

网站

JavaScript (browser, Node.js or React Native)

- Installation steps- API- Source code

JavaScript (for WeChat Mini-Programs)

https://github.com/weapp-socketio/weapp.socket.io

Java

https://github.com/socketio/socket.io-client-java

C++

https://github.com/socketio/socket.io-client-cpp

Swift

https://github.com/socketio/socket.io-client-swift

Dart

https://github.com/rikulo/socket.io-client-dart

Python

https://github.com/miguelgrinberg/python-socketio

.Net

https://github.com/doghappy/socket.io-client-csharp

Rust

https://github.com/1c3t3a/rust-socketio

Kotlin

https://github.com/icerockdev/moko-socket-io

PHP

https://github.com/ElephantIO/elephant.io

Socket.IO 不是什么

Socket.IO 不是 WebSocket 实现。

尽管 Socket.IO 确实在可能的情况下使用 WebSocket 进行传输,但它会向每个数据包添加额外的元数据。这就是为什么 WebSocket 客户端将无法成功连接到 Socket.IO 服务器,并且 Socket.IO 客户端也将无法连接到普通 WebSocket 服务器。

代码语言:javascript
复制
// WARNING: the client will NOT be able to connect!
const socket = io("ws://echo.websocket.org");

Socket.IO 不适合在移动应用的后台服务中使用。

Socket.IO 库与服务器保持开放的 TCP 连接,这可能会导致用户消耗大量电池。对于此用例,请使用专用消息传递平台(例如FCM)。

特性

以下是 Socket.IO 通过普通 WebSocket 提供的功能:

HTTP 长轮询回退

如果无法建立 WebSocket 连接,连接将回退到 HTTP 长轮询。

此功能是十多年前创建 Socket.IO 项目时人们使用 Socket.IO 的第一大原因(!),因为浏览器对 WebSockets 的支持仍处于起步阶段。

即使大多数浏览器现在都支持 WebSocket(超过97%),它仍然是一个很棒的功能,因为我们仍然收到用户的报告,称他们无法建立 WebSocket 连接,因为他们位于某些配置错误的代理后面。

自动重连

在某些特定条件下,服务器和客户端之间的 WebSocket 连接可能会中断,而双方都不知道链接的中断状态。

这就是 Socket.IO 包含心跳机制的原因,该机制会定期检查连接的状态。

当客户端最终断开连接时,它会自动以指数回退延迟重新连接,以免服务器不堪重负。

数据包缓冲

当客户端断开连接时,数据包会自动缓存,并在重新连接时发送。

更多信息在此处。

回执

Socket.IO 提供了一种发送事件和接收响应的便捷方法:

发送者

代码语言:javascript
复制
socket.emit("hello", "world", (response) => {  console.log(response); // "got it"});

接收者

代码语言:javascript
复制
socket.on("hello", (arg, callback) => {  console.log(arg); // "world"  callback("got it");});

你还可以添加超时:

代码语言:javascript
复制
socket.timeout(5000).emit("hello", "world", (err, response) => {  if (err) {    // the other side did not acknowledge the event in the given delay  } else {    console.log(response); // "got it"  }});

广播

在服务器端,你可以向所有连接的客户端或给一部分客户端发送事件:

代码语言:javascript
复制
// to all connected clientsio.emit("hello");// to all connected clients in the "news" roomio.to("news").emit("hello");

这在扩展到多个节点时也有效。

多路复用

命名空间允许你通过单个共享连接拆分应用的逻辑。例如,如果你想要创建只有授权用户才能加入的 "管理" 通道,这可能会很有用。

代码语言:javascript
复制
io.on("connection", (socket) => {  // classic users});io.of("/admin").on("connection", (socket) => {  // admin users});

实战示例

服务器端

服务器端这里使用PHPSocket.IO。PHPSocket.IO是基于Workerman开发的PHP版本的socket.IO服务。可用于服务器消息的推送、聊天室、客服系统的开发。

官方文档:https://github.com/walkor/phpsocket.io

安装
代码语言:javascript
复制
composer require workerman/phpsocket.io

服务端server.php

代码语言:javascript
复制
<?php
/**
 * @desc server.php 描述信息
 * @author Tinywan(ShaoBo Wan)
 */
declare(strict_types=1);

require_once '../vendor/autoload.php';
use Workerman\Worker;
use PHPSocketIO\SocketIO;

// 创建socket.io服务端,监听3120端口
$io = new SocketIO(2024);
// 当有客户端连接时打印一行文字
$io->on('connection', function($socket)use($io){
    echo '[x] new connection coming'.PHP_EOL;
});

Worker::runAll();

启动服务端

代码语言:javascript
复制
php server.php start
客户端
代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>phpsocket.io 客户端</title>
</head>
<body>
<script src='https://cdn.bootcss.com/socket.io/2.0.3/socket.io.js'></script>
<script>
    var socket = io('http://127.0.0.1:2024');
    socket.on('connect', function(){
        console.log('connect success');
    });
</script>
</body>
</html>

浏览器打开后,服务端输出

代码语言:javascript
复制
---------------------------------------------- WORKERMAN -----------------------------------------------
Workerman version:4.1.15          PHP version:7.4.28
----------------------------------------------- WORKERS ------------------------------------------------
worker                                          listen                              processes   status
PHPSocketIO                                     socketIO://0.0.0.0:2024             1           [ok]
[x] new connection coming
[x] new connection coming
[x] new connection coming

自定义事件

socket.io主要是通过事件来进行通讯交互的。socket连接除了自带的connectmessagedisconnect三个事件以外,在服务端和客户端开发者可以自定义其它事件。

服务端和客户端都通过emit方法触发对端的事件。例如下面的代码在服务端定义了一个chat message事件,事件参数为$msg

代码语言:javascript
复制
<?php
require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Worker;
use PHPSocketIO\SocketIO;

$io = new SocketIO(2024);
// 当有客户端连接时
$io->on('connection', function($socket)use($io){
  // 定义chat message事件回调函数
  $socket->on('chat message', function($msg)use($io){
    // 触发所有客户端定义的chat message from server事件
    $io->emit('chat message from server', $msg);
  });
});
Worker::runAll();

客户端通过下面的方法触发服务端的chat message事件。

代码语言:javascript
复制
<script src='//cdn.bootcss.com/socket.io/1.3.7/socket.io.js'></script>
<script>
// 连接服务端
var socket = io('http://127.0.0.1:2024');
// 触发服务端的chat message事件
socket.emit('chat message', '这个是消息内容...');
// 服务端通过emit('chat message from server', $msg)触发客户端的chat message from server事件
socket.on('chat message from server', function(msg){
    console.log('get message:' + msg + ' from server');
});
</script>

workerStart事件

phpsocket.io提供了workerStart事件回调,也就是当进程启动后准备好接受客户端链接时触发的回调。一个进程生命周期只会触发一次。可以在这里设置一些全局的事情,比如开一个新的Worker端口等等。

代码语言:javascript
复制
require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Worker;
use PHPSocketIO\SocketIO;

$io = new SocketIO(9120);

// 监听一个http端口,通过http协议访问这个端口可以向所有客户端推送数据(url类似http://ip:9191?msg=xxxx)
$io->on('workerStart', function()use($io) {
    $inner_http_worker = new Worker('http://0.0.0.0:9191');
    $inner_http_worker->onMessage = function($http_connection, $data)use($io){
        if(!isset($_GET['msg'])) {
            return $http_connection->send('fail, $_GET["msg"] not found');
        }
        $io->emit('chat message', $_GET['msg']);
        $http_connection->send('ok');
    };
    $inner_http_worker->listen();
});

// 当有客户端连接时
$io->on('connection', function($socket)use($io){
  // 定义chat message事件回调函数
  $socket->on('chat message', function($msg)use($io){
    // 触发所有客户端定义的chat message from server事件
    $io->emit('chat message from server', $msg);
  });
});

Worker::runAll();
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-08-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 开源技术小栈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是 Socket.IO
  • 版本差异
  • 语言实现
    • 服务器实现
      • 客户端实现
      • Socket.IO 不是什么
      • 特性
        • HTTP 长轮询回退
          • 自动重连
            • 数据包缓冲
              • 回执
                • 广播
                  • 多路复用
                  • 实战示例
                    • 服务器端
                      • 安装
                      • 客户端
                  • 自定义事件
                  • workerStart事件
                  相关产品与服务
                  腾讯企点客服
                  腾讯企点客服(Tencent QiDian Customer Service)是为销售和客服提供多渠道商机转化与客户服务的智能客服平台。基于腾讯云的即时通讯、音视频、人工智能、大数据、云呼叫中心等技术,以个性化服务和精准客户洞察撬动销售转化与复购增购。企点客服全面覆盖了从销售到服务的全链路业务场景,帮助企业构建一体化的客户运营体系,极大提升了企业获客、待客、留客的效率。
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档