正在移植一个node-cocos的棋牌项目,需求是从8移植到24。在window10系统下用nvm下载8.9.1这个版本,nvm提示下载失败强行终止,所以只能手动配置。如何下载使用nvm请去看nest.js系列第二节里有,这里不做复述。
一、手动下载 Node.js 8.9.1(不要通过 nvm 自动下)
-
下载:node-v8.9.1-win-x64.zip(不要下msi包,之下压缩包)
-
解压到你 nvm 的目录,一般是:
C:\Users\your name\AppData\Local\nvm\v8.9.1\
(要保证v8.9.1里面直接就是 node.exe,不是再套一层文件夹)
v8.9.1直接就带npm5.5.1,直接就可以使用。
这个版本只是运行老项目用,开发新项目需要使用v24.15.0
在24的环境下,把npm源设置为国内的镜像
bash
# 设为淘宝新域名(旧 registry.npm.taobao.org 已失效)
npm config set registry https://registry.npmmirror.com
# 查看是否生效
npm config get registry
创建项目文件夹,在文件夹中执行
npm init
技术选型使用express或者colyseus哪一个还没有定,这里先简介一下
二、Colyseus简介
Colyseus 是 "基于 WebSocket 的多人游戏框架"。
- colyseus.js(客户端) :底层就是 WebSocket,用来连 Colyseus 服务器。
- Colyseus 服务器 :默认用
ws库做 WebSocket 传输,也可以换成更快的uWebSockets.jsColyseus。 - 整个框架核心就是 WebSocket + 房间 + 状态同步。
1. 它和 "纯 ws" 区别
- 纯
ws:你要自己写- 连接管理
- 房间 / 玩家匹配
- 状态同步、广播
- 心跳、断线重连
- Colyseus:帮你把这些都封装好了,但底层仍然是 WebSocket。
2. 最小示例(服务器 + 客户端)
服务器(Node.js)
bash
运行
npm init -y
npm install colyseus
js
// index.js
const { Server } = require("colyseus");
const gameServer = new Server();
// 定义一个房间
gameServer.define("my_room", class MyRoom extends Schema {
onJoin(client) {
console.log("玩家加入");
client.send("hello", "欢迎!");
}
onMessage(client, data) {
console.log("收到:", data);
this.broadcast(data); // 广播给所有人
}
});
gameServer.listen(3000);
console.log("Colyseus 服务器运行在 3000 端口");
客户端(浏览器 /colyseus.js)
html
预览
<script src="https://unpkg.com/colyseus.js@^0.16.0/dist/colyseus.js"></script>
<script>
const client = new Colyseus.Client("ws://localhost:3000");
client.joinOrCreate("my_room").then(room => {
console.log("进入房间");
room.onMessage("hello", msg => console.log(msg));
room.send("test", "来自客户端的消息");
});
</script>
三、Express和msgpack-lite
1. 在项目目录安装依赖(2 个包)
打开终端,进入你的项目文件夹,执行:
bash
运行
npm install express msgpack-lite
2. 创建主文件:index.js
直接复制下面全部代码,保存为 index.js
javascript
运行
const express = require('express');
const msgpack = require('msgpack-lite');
const app = express();
// 支持解析 JSON 入参
app.use(express.json());
// --------------------------
// 接口一:字符串 → msgpack 压缩 → 转 16 进制字符串
// --------------------------
app.get('/encode', (req, res) => {
// 从 url 参数获取字符串,默认用测试字符串
const str = req.query.str || 'hello 游戏服务器 123';
// 1. 字符串转 msgpack 二进制
const buffer = msgpack.encode(str);
// 2. 二进制转 16 进制字符串
const hexStr = buffer.toString('hex');
// 返回结果
res.json({
original: str,
hex: hexStr
});
});
// --------------------------
// 接口二:输入 16 进制字符串 → 还原成正常字符串
// --------------------------
app.post('/decode', (req, res) => {
const { hex } = req.body;
if (!hex) {
return res.status(400).json({ error: '请传入 hex 字段' });
}
try {
// 1. 16进制 → 二进制 buffer
const buffer = Buffer.from(hex, 'hex');
// 2. 解包 msgpack → 原始字符串
const result = msgpack.decode(buffer);
res.json({
hex: hex,
decoded: result
});
} catch (err) {
res.status(400).json({ error: '16进制格式错误,无法解码' });
}
});
// 启动服务
const PORT = 3000;
app.listen(PORT, () => {
console.log(`服务运行在 http://localhost:${PORT}`);
});
3. 启动服务
bash
运行
node index.js
4. 两个接口使用方法
接口一(编码)
GET
plaintext
http://localhost:3000/encode?str=我是测试字符串
返回:
json
{
"original": "我是测试字符串",
"hex": "a5e68891e698afe6b58be8af95e5ad97e7aca6e4b8b2"
}
接口二(解码)
POST
plaintext
http://localhost:3000/decode
Body(JSON):
json
{
"hex": "a5e68891e698afe6b58be8af95e5ad97e7aca6e4b8b2"
}
返回:
json
{
"hex": "a5e68891e698afe6b58be8af95e5ad97e7aca6e4b8b2",
"decoded": "我是测试字符串"
}