在现代 web 应用中,实时性是越来越重要的一个特性。例如在在线拍卖、在线游戏等场景中,用户需要实时地获取其他用户的状态或者数据。而 Socket.io 作为一个实时通讯库,可以用来构建这样的应用。在本文中,我们将探讨如何利用 Socket.io 构建一个在线竞价应用。
竞价应用的基本功能
竞价应用需要支持以下功能:
- 用户可以创建一个竞价房间,其他用户可以加入该房间;
- 房间内的用户可以实时地看到当前竞价的最高价和竞价者;
- 用户可以实时地提交竞价;
- 竞价截止后,系统可以自动选出最高价的竞价者。
技术选型
在本文中,我们将使用以下技术:
- Node.js:作为后端服务器运行环境;
- Express:作为 web 框架;
- Socket.io:作为实时通讯库。
实现步骤
1. 创建 Express 应用
首先,我们需要创建一个 Express 应用。可以使用 Express 应用生成器来快速创建一个模板应用:
$ npm install -g express-generator $ express auction-app $ cd auction-app $ npm install
2. 添加 Socket.io 支持
在 Express 应用中使用 Socket.io 需要进行一些配置。我们可以在 app.js
文件中添加以下代码:
var http = require('http'); var socketio = require('socket.io'); var app = express(); var server = http.createServer(app); var io = socketio(server); app.set('io', io);
这里我们创建了一个 HTTP 服务器,并将其与 Express 应用关联。然后,我们使用 Socket.io 创建了一个实例,并将其设置为 Express 应用的属性,以便在后续的代码中使用。
3. 添加竞价房间的页面
我们需要添加一个页面,让用户可以创建竞价房间。在 views
目录下创建 auction.ejs
文件,内容如下:
-- -------------------- ---- ------- --------- ----- ------ ------ ----- ---------------- ------------------- ------- ------ ----- ------------- ------------------ ------ ----------------------------- ------ -------------- --------------- --------- ------- --------------------------- ------- ------- -------展开代码
这里我们使用了 EJS 模板引擎来生成 HTML。表单中有一个输入框和一个提交按钮,用户可以输入房间名称,并提交表单来创建竞价房间。
4. 处理创建竞价房间的请求
在 routes/index.js
文件中添加以下代码:
-- -------------------- ---- ------- ----------------------- ------------- ---- - --- -- - ------------------ --- -------- - ------------------ --- ---- - ----------------------------------- -- ------ - ------------------ - ---- - --------- - -------------------------- ---------------- - ---------------------- ---------------- ------------- - --------- - ---------------------------------- ----- --- --- ------------------------ - ---------- - ---展开代码
这里我们处理了 /auction
的 POST 请求,获取了房间名称,并检查该房间是否已经存在。如果房间已经存在,我们直接返回一个错误响应。否则,我们使用 Socket.io 创建了一个命名空间,并在该命名空间下添加了一个 connection
事件监听器。当有用户连接到该命名空间时,我们让该用户加入房间,并监听 bid
事件。当用户提交竞价时,我们使用 io.of(namespace).to(roomName).emit(event, data)
方法将竞价信息广播给房间内的所有用户。
5. 添加竞价房间的页面
在 routes/index.js
文件中添加以下代码:
router.get('/auction/:roomName', function(req, res) { var roomName = req.params.roomName; res.render('auction-room', { roomName: roomName }); });
这里我们处理了 /auction/:roomName
的 GET 请求,获取了房间名称,并渲染了一个模板。模板文件为 views/auction-room.ejs
,内容如下:
-- -------------------- ---- ------- --------- ----- ------ ------ ----- ---------------- ----------- - --- -------- ---------- ------- ------ ------- --------------------------------------- -------- --- ------ - -------- -------- ----- --- ------- - ------------------------------------ --- -------- - ------------------------------------- --- ---------- - --------------------------------------- --- ------------- - ------------------------------------------ ---------------- ------------- - -------------------- - ----------- ----------------------- - ----------- --- ---------------------------------- --------------- - ----------------------- --- ------ - ------------------------- ------------------ - ------- ------- ------- ---- -------- --- --- --- --------- ------------ -------- ------- ------------ ------------------------- ----- -------------- -------------------------------- ----- -------------- ------ --------------------------- ------ -------------- ------------- ------- --------- ------- ------------------------- ------- ------- -------展开代码
这里我们使用了之前创建的 Socket.io 实例,并指定了命名空间为 /roomName
。在页面加载完成后,我们监听 bid
事件,并更新最高价和最高出价者的显示。当用户提交竞价时,我们使用 socket.emit(event, data)
方法将竞价信息发送给服务器。
6. 添加自动选出最高价的竞价者的功能
在 routes/index.js
文件中添加以下代码:
-- -------------------- ---- ------- --------------------------------------- ------------- ---- - --- -------- - -------------------- --- -- - ------------------ --- ---- - ----------------------------------- -- ------- - ------------------ - ---- - --- ---------- - -- --- ------------- - ----- ---------------------------------------------------- - --- ------ - ------------------------------- --- --- - ----------- -- ---- -- ---------- - ----------- - ---------- - ----------- ------------- - ----------- - --- ---------------------------- - --------- --------- ----------- ----------- -------------- ------------- --- - ---展开代码
这里我们处理了 /auction/:roomName/result
的 GET 请求,获取了房间名称,并检查该房间是否存在。如果房间不存在,我们直接返回一个错误响应。否则,我们遍历房间内的所有用户,并找到最高价的竞价者。最后,我们渲染了一个模板,显示最高价和最高出价者的信息。模板文件为 views/auction-result.ejs
,内容如下:
-- -------------------- ---- ------- --------- ----- ------ ------ ----- ---------------- ----------- - --- -------- -- - ---------- ------- ------ ------------ -------- ------- -- -- --------------- - -- ---------- ---------- -- ----- ------------ ------------- ------ -- - ---- - -- ----------- -- - -- ------- -------展开代码
示例代码
完整的示例代码可以在 GitHub 上查看:https://github.com/ruanyf/socket.io-demo。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67cb0edce46428fe9e3b23bf