uni-app 186多进程实现
Posted 2019ab
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了uni-app 186多进程实现相关的知识,希望对你有一定的参考价值。
/app.js
class AppBootHook
constructor(app)
this.app = app;
configWillLoad()
// 此时 config 文件已经被读取并合并,但是还并未生效
// 这是应用层修改配置的最后时机
// 注意:此函数只支持同步调用
async didLoad()
// 所有的配置已经加载完毕
// const app = this.app;
// const ctx = await app.createAnonymousContext();
// app.messenger.send
// 可以用来加载应用自定义的文件,启动自定义的服务
async willReady()
// 所有的插件都已启动完毕,但是应用整体还未 ready
// 可以做一些数据初始化等操作,这些操作成功才会启动应用
// 例如:从数据库加载数据到内存缓存
async didReady()
// 应用已经启动完毕
const app = this.app;
const ctx = await app.createAnonymousContext();
app.messenger.on('offline', user_id =>
if (app.ws.user[user_id])
app.ws.user[user_id].send(JSON.stringify(
msg: "fail",
data: '你的账号在其他设备登录'
));
app.ws.user[user_id].close();
);
app.messenger.on('send', e =>
let to_id, message, msg = e;
if (app.ws.user && app.ws.user[to_id])
app.ws.user[to_id].send(JSON.stringify(
msg,
data: message
));
app.ws.user[user.id].close();
);
async serverDidReady()
// http / https server 已启动,开始接受外部请求
// 此时可以从 app.server 拿到 server 的实例
module.exports = AppBootHook;
/app/controller/chat.js
// app/controller/chat.js
const Controller = require('egg').Controller;
class ChatController extends Controller
// 连接socket
async connect()
const ctx, app, service = this;
if (!ctx.websocket)
ctx.throw(400, '非法访问');
// console.log(`clients: $app.ws.clients.size`);
// 监听接收消息和关闭socket
ctx.websocket
.on('message', msg =>
// console.log('接收消息', msg);
)
.on('close', (code, reason) =>
// 用户下线
console.log('用户下线', code, reason);
let user_id = ctx.websocket.user_id;
// 移除redis中的用户上线记录
service.cache.remove('online_' + user_id);
if (app.ws.user && app.ws.user[user_id])
delete app.ws.user[user_id];
);
// 发送消息
async send()
const ctx, app, service = this;
// 拿到当前用户id
let current_user_id = ctx.authUser.id;
// 验证参数
ctx.validate(
to_id:
type: 'int',
required: true,
desc: '接收人/群id'
,
chat_type:
type: 'string',
required: true,
range:
in: ['user', 'group']
,
desc: '接收类型'
,
type:
type: 'string',
required: true,
range:
in: ['text', 'image', 'video', 'audio', 'emoticon', 'card']
,
desc: '消息类型'
,
data:
type: 'string',
required: true,
desc: '消息内容'
,
options:
type: 'string',
required: true
);
// 获取参数
let to_id, chat_type, type, data, options = ctx.request.body;
// 单聊
if (chat_type === 'user')
// 验证好友是否存在,并且对方没有把你拉黑
let Friend = await app.model.Friend.findOne(
where:
user_id: to_id,
friend_id: current_user_id,
isblack: 0
,
include: [
model: app.model.User,
as: "userInfo"
,
model: app.model.User,
as: "friendInfo"
]
);
if (!Friend)
return ctx.apiFail('对方不存在或者已经把你拉黑');
// 验证好友是否被禁用
if (!Friend.userInfo.status)
return ctx.apiFail('对方已被禁用');
// 构建消息格式
let from_name = Friend.friendInfo.nickname ? Friend.friendInfo.nickname : Friend.friendInfo.username;
if (Friend.nickname)
from_name = Friend.nickname;
let message =
id: (new Date()).getTime(), // 唯一id,后端生成唯一id
from_avatar: Friend.friendInfo.avatar,// 发送者头像
from_name, // 发送者昵称
from_id: current_user_id, // 发送者id
to_id, // 接收人/群 id
to_name: Friend.userInfo.nickname ? Friend.userInfo.nickname : Friend.userInfo.username, // 接收人/群 名称
to_avatar: Friend.userInfo.avatar, // 接收人/群 头像
chat_type: 'user', // 接收类型
type,// 消息类型
data, // 消息内容
options: , // 其他参数
create_time: (new Date()).getTime(), // 创建时间
isremove: 0, // 是否撤回
// 视频,截取封面
if (message.type === 'video')
message.options.poster = message.data + '?x-oss-process=video/snapshot,t_10,m_fast,w_300,f_png';
// 音频,带上音频时长
if (message.type === 'audio')
options = JSON.parse(options);
message.options.time = options.time || 1;
// 名片
if (message.type === 'card')
// 验证名片用户是否存在
message.options = JSON.parse(options)
ctx.sendAndSaveMessage(to_id, message);
// 存储到自己的聊天记录中 chatlog_当前用户id_user_对方用户id
service.cache.setList(`chatlog_$current_user_id_$message.chat_type_$to_id`, message);
// 返回成功
return ctx.apiSuccess(message);
// 群聊
// 验证群聊是否存在,且你是否在该群中
let group = await app.model.Group.findOne(
where:
status: 1,
id: to_id
,
include: [
model: app.model.GroupUser,
attributes: ['user_id', 'nickname']
]
);
if (!group)
return ctx.apiFail('该群聊不存在或者已被封禁');
let index = group.group_users.findIndex(item => item.user_id === current_user_id);
if (index === -1)
return ctx.apiFail('你不是该群的成员');
// 组织数据格式
let from_name = group.group_users[index].nickname;
let message =
id: (new Date()).getTime(), // 唯一id,后端生成唯一id
from_avatar: ctx.authUser.avatar,// 发送者头像
from_name: from_name || ctx.authUser.nickname || ctx.authUser.username, // 发送者昵称
from_id: current_user_id, // 发送者id
to_id, // 接收人/群 id
to_name: group.name, // 接收人/群 名称
to_avatar: group.avatar, // 接收人/群 头像
chat_type: 'group', // 接收类型
type,// 消息类型
data, // 消息内容
options: , // 其他参数
create_time: (new Date()).getTime(), // 创建时间
isremove: 0, // 是否撤回
group: group
// 视频,截取封面
if (message.type === 'video')
message.options.poster = message.data + '?x-oss-process=video/snapshot,t_10,m_fast,w_300,f_png';
// 音频,带上音频时长
if (message.type === 'audio')
options = JSON.parse(options);
message.options.time = options.time || 1;
// 名片
if (message.type === 'card')
// 验证名片用户是否存在
message.options = JSON.parse(options)
// 推送消息
group.group_users.forEach(item =>
if (item.user_id !== current_user_id)
ctx.sendAndSaveMessage(item.user_id, message);
);
ctx.apiSuccess(message);
// 获取离线消息
async getmessage()
const ctx, app, service = this;
let current_user_id = ctx.authUser.id;
let key = 'getmessage_' + current_user_id;
let list = await service.cache.getList(key);
// 清除离线消息
await service.cache.remove(key);
// 批量推送
list.forEach(async (message) =>
let d = JSON.parse(message);
ctx.sendAndSaveMessage(current_user_id, d.message, d.msg);
);
// 撤回
async recall()
const ctx, app = this;
let current_user_id = ctx.authUser.id;
ctx.validate(
to_id:
type: 'int',
required: true,
desc: '接收人/群id'
,
chat_type:
type: 'string',
required: true,
range:
in: ['user', 'group']
,
desc: '接收类型'
,
id:
type: 'int',
required: true,
desc: '消息id'
);
let to_id, chat_type, id = ctx.request.body;
let message =
from_id: current_user_id,
to_id,
chat_type,
id
// 单聊
if (chat_type === 'user')
ctx.sendAndSaveMessage(to_id, message, 'recall');
return ctx.apiSuccess(message);
// 群聊
let group = await app.model.Group.findOne(
where:
id: to_id,
status: 1
,
include: [
model: app.model.GroupUser,
attributes: ['user_id']
]
);
if (group)
group.group_users.forEach(item =>
if (item.user_id !== current_user_id)
ctx.sendAndSaveMessage(item.user_id, message, 'recall');
);
return ctx.apiSuccess(message);
module.exports = ChatController;
/app/extend/extend.js
// app/extend/context.js
var qr = require('qr-image');
module.exports =
// 成功提示
apiSuccess(data = '', msg = 'ok', code = 200)
this.body = msg, data ;
this.status = code;
,
// 失败提示
apiFail(data = '', msg = 'fail', code = 400)
this.body = msg, data ;
this.status = code;
,
// 生成token
getToken(value)
return this.app.jwt.sign(value, this.app.config.jwt.secret);
,
// 验证token
checkToken(token)
return this.app.jwt.verify(token, this.app.config.jwt.secret);
,
// 发送或者存到消息队列中
sendAndSaveMessage(to_id,message,msg='ok')
const app,service = this;
let current_user_id = this.authUser.id;
// 拿到当前的socket
// let socket = app.ws.user[to_id];
// 验证对方是否在线,不在线记录到待接收消息队列中 在线:消息推送 存储到对方的聊天记录中 chatlog_对方用户id_user_当前用户id
if(app.ws.user && app.ws.user[to_id])
// 消息推送
app.ws.user[to_id].send(JSON<以上是关于uni-app 186多进程实现的主要内容,如果未能解决你的问题,请参考以下文章