/project/index.js
const bodyParser = require("body-parser");
const express = require("express");
const path = require("path");
const app = express();
const http = require("http");
const { Server } = require("socket.io");
const server = http.createServer(app);
const port = 3005;
/**
* 所有开关的状态记录
*/
const switchs = {
// 台灯开关
desklamp: "0",
};
app.use(bodyParser.json({ limit: "50mb" }));
// for parsing application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: true }));
// 前端静态服务,包括文件和页面
app.use(express.static(path.join(__dirname,"./client")))
app.all("*",function (req,res,next) {
res.set({
"Content-Type": "text/plain",
"Access-Control-Allow-Credentials": "true",
"Access-Control-Allow-Headers": "X-Requested-With,Content-Type,token,authorization",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Origin": req.headers.origin,
"Access-Control-Allow-Methods": "POST,GET",
"Content-Type": "application/json",
});
next();
});
const io = new Server(server,{
allowEIO3: true,
credentials: true,
cors: {},
});
io.on("connection",(socket) => {
try {
console.log("一个新的 scoket 连接");
/**
* 用户连接即推送信息
*/
io.to(socket.id).emit("switchs",switchs);
/**
* 查询请求,返回所有开关状态
*/
socket.on("query",function (data) {
console.log(`[query]`, data ? data : "");
io.to(socket.id).emit("switchs",switchs);
});
/**
* 设置开关状态
* { id: "desklamp", data: "0" | "1" }
*/
socket.on("set",function (body) {
const id = body.id;
const status = body.data;
if(!id) {
console.log('没有传入id,更新失败!')
return
};
switchs[id] = status;
console.log(`[set]`, id, body.data);
// 更新完后广播
io.emit("switchs",switchs);
});
// 发生错误时触发
socket.on("error",function (err) {
console.log("socket 错误:",err);
});
} catch (err) {
console.log("socket 错误:",err);
io.to(socket.id).emit("error",`系统异常:${err}`);
}
});
server.listen(port,() => {
console.log(`服务正在运行: http://localhost:${port}`);
});
代码分析
- 首先是使用
3005
端口启动了一个服务器. - 将
./client
设置为静态文件夹,该文件夹中将会放置客户端页面 - 使用 socket.io 插件实现一个 ws 服务。
- 监听
query
消息,用于返回当前开关状态 - 监听
set
消息,用于改变开关状态
代码中 switchs
写为对象形式是为了方便后期继续扩展别的继电器。