Node.js 基于socket.io的简易聊天程序
1、简单释义
socket.io是一个跨浏览器支持WebSocket的实时通讯的JS。
Socket.io支持及时、双向、基于事件的交流,可在不同平台、浏览器、设备上工作,可靠性和速度稳定。最典型的应用场景如:
- 实时分析:将数据推送到客户端,客户端表现为实时计数器、图表、日志客户。
- 实时通讯:聊天应用
- 二进制流传输:socket.io支持任何形式的二进制文件传输,例如图片、视频、音频等。
- 文档合并:允许多个用户同时编辑一个文档,并能够看到每个用户做出的修改。
Socket.io实际上是WebSocket的父集,Socket.io封装了WebSocket和轮询等方法,会根据情况选择方法来进行通讯。
Node.js提供了高效的服务端运行环境,但由于Browser对HTML5的支持不一,为了兼容所有浏览器,提供实时的用户体验,并为开发者提供客户端与服务端一致的编程体验,于是Socket.io诞生了。
2、应用示例
实现一个极简版的聊天程序,分为客户端代码和服务器端代码
服务端端:
const express = require('express');
const path = require('path');
const app = new express();
//利用 Express 托管静态文件,通过如下代码就可以将 public 目录下的图片、CSS 文件、
//JavaScript 文件对外开放访问了 例如:http://localhost:3000/socket.io.js
app.use(express.static("./public"));
// 绑定HTTP服务器实例,和express结合使用
let httpServer = require('http').createServer(app);
let io = require('socket.io').listen(httpServer);
//绑定端口 socket和server服务器共用同一个端口
httpServer.listen(3000);
//设置路由
app.get('/chat', (req, res) => {
res.sendFile(path.resolve('./chat-socketio.html'));
});
let onlinePeopleNum = 0;
let ryMap = {};
// 服务端监听连接状态:io的connection事件表示客户端与服务端成功建立连接,
// 它接收一个回调函数,回调函数会接收一个socket参数。
io.on('connection', (socket) => {
onlinePeopleNum++;
console.log('有1个用户进入聊天室,当前在线人数:'+onlinePeopleNum);
// 接收客户端发送的消息
socket.on('user login', (data) => {
console.log(data.name);
ryMap[socket.id]=data.name;
// io.to(socket.id).emit方法用于向指定的客户端发送消息,
// 参数1表示自定义的事件名,参数2表示传入事件的参数
io.to(socket.id).emit('welcome message',`欢迎${data.name}进入聊天室!`);
socket.broadcast.emit('broadcast', `欢迎${data.name}进入聊天室!`);
});
// 监听断开连接状态:socket的disconnect事件表示客户端与服务端断开连接
socket.on('disconnect', () => {
let name = ryMap[socket.id];
onlinePeopleNum--;
console.log(`${name}离开聊天室,当前在线人数:${onlinePeopleNum}`);
});
// 接收客户端发送的消息
socket.on('client message', (data) => {
let name = ryMap[socket.id];
io.emit('broadcast', `${name}:${data.msg}` );
});
});
客户端:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Chat</title>
<script src="https://cdn.bootcss.com/socket.io/1.7.3/socket.io.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="./socket.io.js"></script>
</head>
<body>
<div id="app">
<div id="name"></div>
<input type="text" v-model="message" />
<button @click="send">发送</button>
<div id="content"> </div>
</div>
<script>
const userName = ['张三', '李四', '王五', '李铭', '李雷', '韩梅梅', 'Tom', 'Lily'];
// 模拟用户名
let name = userName[Math.floor(Math.random() * 8)];
// socket.io引入成功后,可通过io()生成客户端所需的socket对象。
let socket = io('http://localhost:3000');
var app = new Vue({
el: '#app',
data: {
message: '',
},
methods: {
send: function () {
// socket.emit()用户客户端向服务端发送消息,服务端与之对应的是socket.on()来接收信息。
socket.emit('client message', { msg: this.message });
}
},
mounted: function () {
document.querySelector('#name').innerHTML = '我的昵称:' + name;
socket.on('connect', () => {
console.log('连接服务器成功!');
});
socket.on('disconnect', () => {
console.log('服务器异常,已与服务器失去联系');
});
socket.on('welcome message', (message) => {
//console.log(message);
// 获取内容显示区域Node
let con = document.querySelector('#content');
con.innerHTML = con.innerHTML + '<br/>' + message;
});
socket.on('broadcast', (message) => {
//console.log(message);
// 获取内容显示区域Node
let con = document.querySelector('#content');
con.innerHTML = con.innerHTML + '<br/>' + message;
});
socket.emit('user login', { name: '' + name });
}
})
</script>
</body>
</html>
界面截图
3、遇到的问题
GET http://localhost:3000/socket.io/?EIO=3&transport=polling&t=Me0Csia net::ERR_CONNECTION_REFUSED
如果遇到上面的错误,如果文件的路径都正确的话,可能的原因就是服务器没有启动
socket.io.js下载地址
链接: https://pan.baidu.com/s/1BeOse0CaxyYmnlA9LiQtIQ 提取码: 54bg