Socket.io双向通信教程,基本使用方式范例
发布于 作者:苏南大叔 来源:程序如此灵动~
基于websocket的最出名的代码框架,就是socket.io了。Socket.IO是一个用于实时双向事件通信的库,它建立在 WebSocket协议之上,同时也支持其他一些传输方式(如轮询)。非常适合构建实时应用程序,比如聊天应用、实时通知系统、在线游戏等。

苏南大叔的“程序如此灵动”博客,记录苏南大叔的代码编程经验总结。测试环境:win10,nodejs@20.18.0,express@4.21.2,socket.io@4.8.1。虽然socket.io是在nodejs代码下出现并发展的,但是,其它高级编程语言(例如python),也是可以使用socket.io的。本文以nodejs为例进行演示。
socket.io 与 websocket
websocket并不是socket.io,socket.io也并不是websocket。两者虽然非常相似,但是并不是同样的事物。socket.io使用的基本部分,包括websocket,也包括传统的轮询。具体使用的协议,是根据实际情况而设定的。socket.io相比较websocket而言,
- 最大最明显的改进是“断线重连”,这个功能非常实用。
- 自带广播功能,不用再次造轮子实现。
socket.io官网:
- https://socket.io/zh-CN/
- https://socket.io/zh-CN/docs/v4/
- https://socket.io/zh-CN/docs/v4/tutorial/introduction

socket.io包括服务器端和客户端两部分,而websocket仅仅需要服务端引用,客户端是浏览器内置的。当然,存在一小部分浏览器不支持websocket的情况,这个时候,socket.io就显露出其重要性了。这里仅展示最基础的收发消息的socket.io的例子,其它的使用情况,后续补充。
服务端
npm i socket.io --save单独使用
socket.io可以单独使用,单独监听端口。比如:
const socketio = require("socket.io");
const io = socketio(3000);运行是能运行,也确实可以对接。不过,对接的时候,因为和伺服的页面不在同一个域名(端口)下面,就会遇到各种各样的跨域问题,令人头疼。
配合其它使用
所以,一般在启动socket.io服务的时候,会复用某个http服务的端口,以规避跨域问题。这里的socket.io以依赖最常见的express服务为例。
let express = require("express");
let app = express();
app.use(express.static('public'));
let expressServer = app.listen(80, () => console.log('http://localhost:%s', expressServer.address().port));
const socketio = require("socket.io");
const io = socketio(expressServer);向客户端发送消息
io.on("connection", (socket) => {
io.to(socket.id).emit("message", "服务器欢迎你");
socket.on("message", (msg) => {
io.to(socket.id).emit("message", "服务器收到你的消息了," + msg);
});
});这里的io.to(socket.id).emit(),和io.emit()是有区别的。
- 前者
io.to(socket.id).emit(),是仅仅发送给当前的这个socket。 - 后者
io.emit(),是无差别的发送给所有人(系统广播,村长也跑不了),类似于广播(村长广播,不发给村长)。

客户端
放了一个test.html在public目录下面,代码如下:
<script src="/socket.io/socket.io.js"></script>
<script>
const socket = io();
socket.emit('message', "Hello, Server!");
socket.on('message', message => {
console.log(message);
});
</script>
这代码,表面上看起来挺简单。但是,仔细瞅的话,就充满了各种各样的疑问。
- 服务器上并没有
/socket.io/socket.io.js这个文件,它的出现是匪夷所思的。当然,你可以选择网络地址加载它,或者换个路径名称加载它。 - 它没写服务器地址,类似
ws:://localhost之类的字样,是没有的。所以,这里比如是有个默认的值。 - 它虽然有
on('message'),但是使用.emit()代替了.send()。或者说.emit('message',msg)==.send(msg)。
结语
本文仅仅涉及socket.io的最基本的收发消息的代码,更多其它技术细节待后续文章讨论。