去饭店吃饭的时候,桌上都会有一个二维码,每一桌的每一个用户都可以拿出手机独立点餐,而且同一桌的用户点餐都会在同一个购物车里,比如张三与李四一起来吃饭,张三点了青椒炒肉,李四拿出手机点餐的时候,购物车里就会显示张三点的青椒炒肉,而且每一桌的点餐与其他桌的不会相互干扰,付款的时候以桌为单位独立结账。
以上就是基本的业务场景,那么这个功能如何实现呢?下面直接上代码,请大家留意注释。
首先是服务端的实现。
// 1.安装
// npm i -S koa-socket
var Koa = require('koa');
var router = require('koa-router')();
var views = require('koa-views');
var url = require('url');
// 2.引入koa-socket
const IO = require('koa-socket');
// 3.实例化koa-socket
const io = new IO();
var app = new Koa();
// 4.把socket.io与app相结合
io.attach(app);
app.use(views('views', {
extension: 'ejs'
}));
router.get('/', async (ctx) => {
let title = "你好EJS";
await ctx.render('index', {
title: title
});
});
app.use(router.routes());
app.use(router.allowedMethods());
// 5.建立连接
app._io.on('connection', socket => {
// 获取桌号
var desk_id = url.parse(socket.request.url, true).query.desk_id;
// 6.将桌号添加到分组
socket.join(desk_id);
// 7.监听客户端添加购物车事件
socket.on('addCart', function (data) {
// 8.发给指定客户,谁发消息给服务器回复给谁
// socket.emit('serverEmit','我接收到增加购物车的事件了');
// 9.广播给所有客户端
// app._io.emit('serverEmit','我接收到增加购物车的事件了');
// 10.回复消息给按桌号分组的用户
// app._io.to(desk_id).emit('serverEmit','我接收到增加购物车的事件了');
// 11.回复消息给按桌号分组的用户,但不包括自己
socket.broadcast.to(desk_id).emit('serverEmit', '我接收到增加购物车的事件了');
})
});
app.listen(3000);
简单说明一下,基本的实现原理为:为每一桌添加一个唯一的桌号,用户扫码的时候,将桌号发给服务端,服务端通过socket.join这个方法将桌号进行分组,用户添加购物车时,服务端只回复以桌号为分组的所有扫码用户。其中 app._io.to( ).emit( ) 这个方法会对该桌所有的用户回复消息,而 socket.broadcast.to( ).emit( ) 会回复给该桌的所用户,但不包括自己。
以下是客户端的基本原理实现。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Koa结合socket.io实现分桌点餐</title>
<!-- 1.引入服务器上存放的socket.io.js -->
<script src="http://192.168.0.3:3000/socket.io/socket.io.js"></script>
</head>
<body>
<h1>餐桌一</h1>
<input type="button" value="加入购物车" onclick="addCart()">
<script type="text/javascript">
// 2.和服务器建立长连接,desk_id为桌号,每一桌都有一个唯一的桌号
var socket = io.connect('http://192.168.0.3:3000?desk_id=1');
function addCart() {
// 3.向服务端发送数据
socket.emit('addCart', 'addCart');
};
// 4.接收服务器返回的信息
socket.on('serverEmit', function (data) {
console.log(data);
});
</script>
</body>
</html>