聊天:加入玩家发起的群聊和测试用例

This commit is contained in:
liangtongchuan
2021-03-05 21:23:28 +08:00
parent d43fd51e9a
commit 5842723458
10 changed files with 195 additions and 23 deletions

View File

@@ -1,7 +1,7 @@
import {Application, BackendSession} from 'pinus';
import { resResult } from '../../../pubUtils/util';
import { DEFAULT_MSG_PER_PAGE, STATUS } from '../../../consts';
import { createPrivateMsg, getPrivateMessages, pushMsgToRole } from '../../../services/chatService';
import { createGroupMsg, createPrivateMsg, getPrivateMessages, groupRoomId, pushGroupMsgToRoom, pushMsgToRole } from '../../../services/chatService';
export default function(app: Application) {
@@ -79,6 +79,12 @@ export class ChatHandler {
*/
async sendGroupMessage(msg: { channel: string, channelId: string, type: number, content: string, targetRoleId: string, targetMsgCode: string }, session: BackendSession) {
const { channel, channelId, type, content, targetRoleId, targetMsgCode } = msg;
const roleId = session.get('roleId');
const roleName = session.get('roleName');
const msgData = await createGroupMsg(roleId, roleName, channel, channelId, type, content, targetRoleId, targetMsgCode);
await pushGroupMsgToRoom(groupRoomId(channel, channelId), msgData);
if (!msgData) return resResult(STATUS.WRONG_PARMS);
return resResult(STATUS.SUCCESS);
}
/**

View File

@@ -1,8 +1,10 @@
import { GroupMessageType } from './../../../db/GroupMessage';
import { Application, ChannelService, FrontendSession, RemoterClass, pinus } from 'pinus';
import { Application, ChannelService } from 'pinus';
import { resResult } from '../../../pubUtils/util';
import { STATUS } from '../../../consts';
import { ON_ADD_CHANNEL_ROUTE, ON_GROUP_MSG_ROUTE, STATUS } from '../../../consts';
import { PrivateMessageType } from '../../../db/PrivateMessage';
import { addUserToChannel } from '../../../services/roleService';
import { ChannelUser } from '../../../domain/ChannelUser';
export default function (app: Application) {
return new ChatRemote(app);
@@ -40,15 +42,13 @@ export class ChatRemote {
public async addWorldChannel(roleId: string, serverId: number, sid: string, flag: boolean = true) {
const name = `world${serverId}`;
let channel = this.channelService.getChannel(name, flag);
if (!channel) return;
channel.add(roleId, sid);
let param = {
roleId
};
channel.pushMessage('onWorldAdd', resResult(STATUS.SUCCESS, param));
if (!!channel) {
channel.add(roleId, sid);
}
return this.getWorldChannel(name);
}
@@ -86,10 +86,8 @@ export class ChatRemote {
let channel = this.channelService.getChannel(name, false);
// leave channel
if (!!channel) {
channel.leave(roleId, sid);
}
if (!channel) return;
channel.leave(roleId, sid);
let param = {
roleId
};
@@ -120,7 +118,10 @@ export class ChatRemote {
* @memberof ChatRemote
*/
public async addChannel(channelName: string, roleId: string, sid: string) {
let channel = this.channelService.getChannel(channelName, true);
if (!channel) return;
addUserToChannel(channel, new ChannelUser(roleId, sid));
channel.pushMessage(ON_ADD_CHANNEL_ROUTE, resResult(STATUS.SUCCESS, { roleId, channelName }));
}
/**
@@ -131,7 +132,15 @@ export class ChatRemote {
* @memberof ChatRemote
*/
public async leaveChannel(channelName: string, roleId: string, sid: string) {
let channel = this.channelService.getChannel(channelName, false);
// leave channel
if (!channel) return;
channel.leave(roleId, sid);
let param = {
roleId,
channelName
};
channel.pushMessage('onLeave', resResult(STATUS.SUCCESS, param));
}
/**
@@ -139,8 +148,10 @@ export class ChatRemote {
* @param {Partial<GroupMessageType>} msg
* @memberof ChatRemote
*/
public async sendGroupMsg(msg: Partial<GroupMessageType>) {
public async sendGroupMsg(roomId: string, msg: Partial<GroupMessageType>) {
let channel = this.channelService.getChannel(roomId, false);
if (!channel) return;
channel.pushMessage(ON_GROUP_MSG_ROUTE, resResult(STATUS.SUCCESS, msg));
}
/**
@@ -151,5 +162,4 @@ export class ChatRemote {
public async sendPrivateMsg(msg: Partial<PrivateMessageType>) {
}
}
}

View File

@@ -19,6 +19,7 @@ import { GuildModel } from '../../../db/Guild';
import { gameData } from '../../../pubUtils/data';
import { getMails } from '../../../services/mailService';
import { addRoleToGuildChannel, addRoleToSysChannel, addRoleToWorldChannel, leaveGuildChannel, leaveSysChannel, leaveWorldChannel } from '../../../services/chatService';
export default function (app: Application) {
return new EntryHandler(app);
}
@@ -88,7 +89,8 @@ export class EntryHandler {
// put user into channel
// console.log(JSON.stringify(self.app.rpc.battle))
// await self.app.rpc.battle.battleRemote.add.route(session)(role.roleId, self.app.get('serverId'), role.serverId, true);
addRoleToSysChannel(role.roleId, self.app.get('serverId'), role.serverId);
addRoleToWorldChannel(role.roleId, self.app.get('serverId'), role.serverId);
await self.app.rpc.chat.chatRemote.addWorldChannel.route(session)(role.roleId, serverId, self.app.get('serverId'));
await self.app.rpc.chat.guildRemote.enterMyChannel.route(session)(role.roleId, self.app.get('serverId'));
let heros = await HeroModel.findByRole(role.roleId, [], HERO_SELECT.ENTRY, true);
@@ -110,6 +112,7 @@ export class EntryHandler {
if(userGuild) {
let guild = await GuildModel.findGuild(userGuild.guildCode, role.serverId, GUILD_SELECT.ENTRY);
if(guild) {
addRoleToGuildChannel(role.roleId, self.app.get('serverId'), guild.code);
role['guildAuth'] = userGuild.auth;
let {lv: guildLv, memberCnt} = guild;
let dicGuild = gameData.centerBase.get(guildLv);
@@ -132,7 +135,7 @@ export class EntryHandler {
* @param {Object} session current session object
*
*/
onUserLeave(session: FrontendSession, reason: string) {
async onUserLeave(session: FrontendSession, reason: string) {
if (!session || !session.uid) {
return;
}
@@ -148,6 +151,9 @@ export class EntryHandler {
// this.app.rpc.battle.battleRemote.kick.route(session)(roleId, this.app.get('serverId'), serverId);
this.app.rpc.chat.chatRemote.kickWorldChannel.route(session, true)(roleId, sid, serverId);
this.app.rpc.chat.guildRemote.leaveMyChannel.route(session)(roleId, sid);
await leaveSysChannel(roleId, sid, serverId);
await leaveWorldChannel(roleId, sid, serverId);
await leaveGuildChannel(roleId, sid);
RoleModel.updateRoleInfo(roleId, { quitTime: nowSeconds() });
}

View File

@@ -1,3 +1,5 @@
import { RoleModel } from './../db/Role';
import { GroupMessageModel } from './../db/GroupMessage';
import { CounterModel } from './../db/Counter';
import { STATUS } from './../consts/statusCode';
import { PrivateMessageModel, PrivateMessageParam, PrivateMessageType } from './../db/PrivateMessage';
@@ -5,7 +7,8 @@ import { GroupMessageParam, GroupMessageType } from '../db/GroupMessage';
import { genCode, resResult } from '../pubUtils/util';
import { pinus } from 'pinus';
import { MSG_CODE_LEN, MSG_STATUS, ON_MSG_ROUTE } from '../consts';
import { getRoleOnlineInfo } from './redisService';
import { addRedisChannel, getRoleOnlineInfo, redisChannelServer } from './redisService';
import { crc32 } from 'crc';
/**
* @description 生成私聊房间号
@@ -63,6 +66,13 @@ async function createPrivateMsgData(roleId: string, roleName: string, type: numb
return result;
}
async function createGroupMsgData(roleId: string, roleName: string, channel: string, channelId: string, type: number, content: string, targetRoleId: string, targetMsgCode: string) {
const result: GroupMessageParam = {roleId, roleName, channel, channelId, type, content, targetRoleId, targetMsgCode};
result.roomId = groupRoomId(channel, channelId);
await setupBaseMsgParm(result);
return result;
}
/**
* @description 数据库中创建私聊数据
* @export
@@ -105,4 +115,72 @@ export async function pushMsgToRole(targetRoleId: string, msg: PrivateMessageTyp
export async function getPrivateMessages(roleId: string, targetRoleId: string, fromSeqId: number, count: number) {
const result = await PrivateMessageModel.getMsgs(privateRoomId(roleId, targetRoleId), fromSeqId, count);
return result;
}
export async function createGroupMsg(roleId: string, roleName: string, channel: string, channelId: string, type: number, content: string, targetRoleId: string, targetMsgCode: string) {
const msgData: GroupMessageParam = await createGroupMsgData(roleId, roleName, channel, channelId, type, content, targetRoleId, targetMsgCode);
const result: GroupMessageType = await GroupMessageModel.createMsg(msgData);
return result;
}
export async function pushGroupMsgToRoom(roomId: string, msg: GroupMessageType) {
const channelSid = await channelServer(roomId);
await pinus.app.rpc.chat.chatRemote.sendGroupMsg.toServer(channelSid, roomId, msg);
}
export async function channelServer(roomId: string) {
const existSid = await redisChannelServer(roomId);
if (existSid) {
return existSid;
}
const servers = pinus.app.getServersByType('chat');
if (!servers || !servers.length) return null;
let index = Math.abs(crc32(roomId)) % servers.length;
const newSid = servers[index].id;
const addResult = await addRedisChannel(roomId, newSid);
if (!addResult) return null;
return newSid;
}
async function addRoleToChannel(roomId: string, roleId: string, sid: string) {
const channelSid = await channelServer(roomId);
await pinus.app.rpc.chat.chatRemote.addChannel.toServer(channelSid, roomId, roleId, sid);
}
export async function addRoleToSysChannel(roleId: string, sid: string, serverId: number) {
const roomId = groupRoomId('sys', `${serverId}`);
await addRoleToChannel(roomId, roleId, sid);
}
export async function addRoleToWorldChannel(roleId: string, sid: string, serverId: number) {
const roomId = groupRoomId('new_world', `${serverId}`);
await addRoleToChannel(roomId, roleId, sid);
}
export async function addRoleToGuildChannel(roleId: string, sid: string, guildCode: string) {
const roomId = groupRoomId('new_guild', guildCode);
await addRoleToChannel(roomId, roleId, sid);
}
async function leaveChannel(roomId: string, roleId: string, sid: string) {
const channelSid = await channelServer(roomId);
await pinus.app.rpc.chat.chatRemote.leaveChannel.toServer(channelSid, roomId, roleId, sid);
}
export async function leaveSysChannel(roleId: string, sid: string, serverId: number) {
const roomId = groupRoomId('sys', `${serverId}`);
await leaveChannel(roomId, roleId, sid);
}
export async function leaveWorldChannel(roleId: string, sid: string, serverId: number) {
const roomId = groupRoomId('new_world', `${serverId}`);
await leaveChannel(roomId, roleId, sid);
}
export async function leaveGuildChannel(roleId: string, sid: string) {
const { guildCode } = await RoleModel.findByRoleId(roleId, 'guildCode');
if (!guildCode) return;
const roomId = groupRoomId('new_guild', guildCode);
await leaveChannel(roomId, roleId, sid);
}

View File

@@ -346,12 +346,12 @@ export function redisSidKey(roleId: string) {
}
export async function redisChannelServer(roomId: string) {
const sid = await redisClient().hgetAsync(REDIS_KEY.ONLINE_USERS, roomId);
const sid = await redisClient().hgetAsync(REDIS_KEY.CHANNEL_SERVERS, roomId);
return sid;
}
export async function addRedisChannel(roomId: string, sid: string) {
const result = await redisClient().hsetAsync(REDIS_KEY.ONLINE_USERS, roomId, sid);
const result = await redisClient().hsetAsync(REDIS_KEY.CHANNEL_SERVERS, roomId, sid);
return result;
}

View File

@@ -1,6 +1,7 @@
import { PinusWSClient } from 'pinus-robot-plugin';
import { expect } from 'chai';
import { checkSuccessResponse } from './CheckPatten';
import { ON_ADD_CHANNEL_ROUTE } from '../app/consts';
export class Client {
private _client;
@@ -19,6 +20,11 @@ export class Client {
this._client.request('connector.entryHandler.debugQueryToken', {tel, magicWord: 'zyz666server518'}, (res) => {
checkSuccessResponse(res);
expect(res.data.token).to.be.an('string');
this._client.on(ON_ADD_CHANNEL_ROUTE, (msg) => {
checkSuccessResponse(msg);
expect(msg.data.roleId).to.be.a('string');
expect(msg.data.channelName).to.be.a('string');
});
this._client.request('connector.entryHandler.enter', {serverId: 1, ...res.data}, (enterRes) => {
// 消息回调
// console.log('connector返回');

View File

@@ -1,4 +1,4 @@
import { DEFAULT_MSG_PER_PAGE, MSG_TYPE, ON_MSG_ROUTE } from './../app/consts';
import { DEFAULT_MSG_PER_PAGE, MSG_TYPE, ON_MSG_ROUTE, ON_GROUP_MSG_ROUTE, CHANNEL_PREFIX } from './../app/consts';
import { Client } from './Client';
import 'mocha';
import { PinusWSClient } from 'pinus-robot-plugin';
@@ -13,6 +13,40 @@ function sendPrivateMessageParm(targetRoleInfo, msg) {
return result;
}
function sendGroupMessageParm(channel, channelId, msg) {
const result = {channel, channelId, ...msg};
return result;
}
function checkGroupMsg(msg, roleId, roomId, content) {
expect(msg.content).to.equal(TEXT_MSG.content);
expect(msg.roleId).to.equal(roleId);
expect(msg.content).to.equal(content);
expect(msg.roomId).to.equal(roomId);
}
function testGroupMsg(pinusClient: PinusWSClient, roleInfo: any, pinusClientT: PinusWSClient, channel: string, channelId: string, done: Mocha.Done) {
let msgReceiveCnt = 0;
const roomId = `${channel}_${channelId}`;
pinusClientT.on(ON_GROUP_MSG_ROUTE, (res) => {
checkSuccessResponse(res);
checkGroupMsg(res.data, roleInfo.roleId, roomId, TEXT_MSG.content);
msgReceiveCnt += 1;
});
pinusClient.on(ON_GROUP_MSG_ROUTE, (res) => {
checkSuccessResponse(res);
checkGroupMsg(res.data, roleInfo.roleId, roomId, TEXT_MSG.content);
msgReceiveCnt += 1;
});
pinusClient.request('chat.chatHandler.sendGroupMessage', sendGroupMessageParm(channel, channelId, TEXT_MSG), (res) => {
checkSuccessResponse(res, false);
setTimeout(() => {
expect(msgReceiveCnt).to.be.equal(2);
done();
}, 1000);
});
}
describe('聊天测试', function() {
let pinusClient: PinusWSClient;
let pinusClientT: PinusWSClient; // 用做测试队友
@@ -72,4 +106,12 @@ describe('聊天测试', function() {
})
}, 1000);
});
it('测试系统频道消息', function(done) {
testGroupMsg(pinusClient, roleInfo, pinusClientT, CHANNEL_PREFIX.SYS, roleInfo.serverId, done);
});
it('测试世界频道消息', function(done) {
testGroupMsg(pinusClient, roleInfo, pinusClientT, CHANNEL_PREFIX.WORLD, roleInfo.serverId, done);
});
});

View File

@@ -11,6 +11,14 @@ export const MSG_TYPE = {
IMG: 2
}
export const CHANNEL_PREFIX = {
SYS: 'sys',
WORLD: 'new_world',
GUILD: 'new_guild',
}
export const ON_MSG_ROUTE = 'onMessage';
export const ON_GROUP_MSG_ROUTE = 'onGroupMessage';
export const ON_ADD_CHANNEL_ROUTE = 'onAddChannel';
export const DEFAULT_MSG_PER_PAGE = 10;

View File

@@ -225,6 +225,7 @@ export const REDIS_KEY = {
GUILD_ACTIVE_RANK: "guildActiveRank", // 公会周活跃排行榜
DB_GAME: 'db_game', // 服务器列表
ONLINE_USERS: 'onlineUsers', // 在线用户情况
CHANNEL_SERVERS: 'chat:channelServers', // 渠道对应的 chat 服务器 Id
}
// 各排行榜对应hash的key

View File

@@ -39,6 +39,21 @@ export default class GroupMessage extends BaseModel {
@prop({ required: true, default: '' })
content: string; // 消息内容
public static async createMsg(data: GroupMessageParam) {
const result = await GroupMessageModel.findOneAndUpdate({ msgCode: data.msgCode }, {...data}, {upsert: true, new: true}).lean();
return result;
}
public static async findOneMsg(query: GroupMessageParam) {
const result = await GroupMessageModel.findOne(query).lean();
return result;
}
public static async getMsgs(roomId: string, fromSeqId: number, count: number) {
const result = await GroupMessageModel.find({ roomId, seqId: { $lt: fromSeqId } }).sort({ seqId: -1 }).limit(count).lean();
return result;
}
}