修复聊天闪退bug,添加对接聊天服务器
This commit is contained in:
parent
3f5dd9ddaf
commit
a676fe8cd0
@ -7,6 +7,7 @@ import logManager, { LogCategory, LogEventType } from './logtext';
|
||||
import settingsService from './SettingsService';
|
||||
import { DatabaseService } from './DatabaseService';
|
||||
import http from '@ohos.net.http';
|
||||
import { JSON } from '@kit.ArkTS';
|
||||
|
||||
// 课堂会话状态
|
||||
export enum ClassSessionStatus {
|
||||
@ -52,8 +53,8 @@ export class ClassSessionModel {
|
||||
questions: QuestionModel[] = []; // 课堂题目列表
|
||||
messages: MessageModel[] = []; // 课堂消息列表
|
||||
|
||||
constructor(sessionId: string = '',
|
||||
className: string = '',
|
||||
constructor(sessionId: string = '',
|
||||
className: string = '',
|
||||
classCode: string = '',
|
||||
teacherAccount: string = '',
|
||||
teacherName: string = '') {
|
||||
@ -96,8 +97,8 @@ export class MessageModel {
|
||||
content: string = ''; // 消息内容
|
||||
timestamp: Date = new Date(); // 发送时间
|
||||
|
||||
constructor(senderId: string = '',
|
||||
senderName: string = '',
|
||||
constructor(senderId: string = '',
|
||||
senderName: string = '',
|
||||
senderRole: SenderRole,
|
||||
content: string = '') {
|
||||
this.id = Date.now().toString(36) + Math.random().toString(36).substring(2);
|
||||
@ -107,6 +108,22 @@ export class MessageModel {
|
||||
this.content = content;
|
||||
this.timestamp = new Date();
|
||||
}
|
||||
|
||||
static fromJSON(jsons: string): MessageModel {
|
||||
let json = JSON.parse(jsons) as Map<string,object>
|
||||
const msg = new MessageModel(
|
||||
json["id"] as string,
|
||||
json["senderId"] as string,
|
||||
json["senderName"] as SenderRole,
|
||||
json["content"] as string
|
||||
);
|
||||
msg.timestamp = new Date();
|
||||
return msg;
|
||||
}
|
||||
|
||||
public useTime(){
|
||||
this.timestamp = new Date()
|
||||
}
|
||||
}
|
||||
|
||||
// 题目模型
|
||||
@ -122,8 +139,8 @@ export class QuestionModel {
|
||||
answers: QuestionAnswer[] = []; // 学生答案列表
|
||||
classCode: string = ''; // 关联的课堂暗号
|
||||
|
||||
constructor(title: string = '',
|
||||
options: QuestionOption[] = [],
|
||||
constructor(title: string = '',
|
||||
options: QuestionOption[] = [],
|
||||
correctOption: number = 0,
|
||||
duration: number = 30,
|
||||
classCode: string = '') {
|
||||
@ -146,8 +163,8 @@ export class QuestionAnswer {
|
||||
timestamp: Date = new Date(); // 提交时间
|
||||
isCorrect: boolean = false; // 是否正确
|
||||
|
||||
constructor(studentAccount: string = '',
|
||||
studentName: string = '',
|
||||
constructor(studentAccount: string = '',
|
||||
studentName: string = '',
|
||||
selectedOption: number = 0,
|
||||
correctOption: number = 0) {
|
||||
this.studentAccount = studentAccount;
|
||||
@ -181,7 +198,7 @@ export interface HttpRequestOptions {
|
||||
method: number; // http.RequestMethod enum value
|
||||
header?: object;
|
||||
extraData?: string;
|
||||
connectTimeout?: number;
|
||||
connectTimeout?: number;
|
||||
readTimeout?: number;
|
||||
}
|
||||
|
||||
@ -210,7 +227,7 @@ export interface CreateSessionRequest {
|
||||
}
|
||||
|
||||
export interface JoinSessionRequest {
|
||||
classCode: string;
|
||||
classCode: string;
|
||||
studentAccount: string;
|
||||
studentName: string;
|
||||
}
|
||||
@ -263,54 +280,54 @@ const TIAN_CHANNEL_TAG = 'tianChannel'; // 自定义TAG用于筛选日志
|
||||
export class ClassRoomService {
|
||||
private static instance: ClassRoomService;
|
||||
private dbService: DatabaseService = DatabaseService.getInstance();
|
||||
|
||||
|
||||
// 当前课堂会话
|
||||
private currentSession: ClassSessionModel | null = null;
|
||||
private currentClassCode: string = '';
|
||||
|
||||
|
||||
// 回调函数集合
|
||||
private eventCallbacks: Map<string, Array<EventCallback>> = new Map();
|
||||
|
||||
|
||||
// 是否已连接
|
||||
private connected: boolean = false;
|
||||
|
||||
|
||||
// 是否为教师
|
||||
private isTeacher: boolean = false;
|
||||
|
||||
|
||||
// 消息轮询定时器ID
|
||||
private pollTimerId: number = -1;
|
||||
|
||||
|
||||
// 最后接收的消息ID
|
||||
private lastMessageId: string = '';
|
||||
|
||||
|
||||
// 最后接收的题目ID
|
||||
private lastQuestionId: string = '';
|
||||
|
||||
|
||||
private constructor() {
|
||||
// 初始化
|
||||
hilog.info(TIAN_CHANNEL_DOMAIN_ID, TIAN_CHANNEL_TAG, 'ClassRoom Service Initialized');
|
||||
}
|
||||
|
||||
|
||||
public static getInstance(): ClassRoomService {
|
||||
if (!ClassRoomService.instance) {
|
||||
ClassRoomService.instance = new ClassRoomService();
|
||||
}
|
||||
return ClassRoomService.instance;
|
||||
}
|
||||
|
||||
|
||||
// 创建HTTP请求客户端
|
||||
private createHttpClient(): http.HttpRequest {
|
||||
let httpRequest = http.createHttp();
|
||||
return httpRequest;
|
||||
}
|
||||
|
||||
|
||||
// 发起HTTP POST请求
|
||||
private async postRequest(endpoint: string, data: object): Promise<ChannelApiResponse> {
|
||||
hilog.info(TIAN_CHANNEL_DOMAIN_ID, TIAN_CHANNEL_TAG, `开始POST请求: ${endpoint}`);
|
||||
try {
|
||||
hilog.info(TIAN_CHANNEL_DOMAIN_ID, TIAN_CHANNEL_TAG, `创建HTTP客户端`);
|
||||
const httpRequest = this.createHttpClient();
|
||||
|
||||
|
||||
// 记录请求数据摘要
|
||||
let dataStr = "";
|
||||
try {
|
||||
@ -319,7 +336,7 @@ export class ClassRoomService {
|
||||
dataStr = "无法序列化数据";
|
||||
}
|
||||
hilog.info(TIAN_CHANNEL_DOMAIN_ID, TIAN_CHANNEL_TAG, `请求数据(摘要): ${dataStr}`);
|
||||
|
||||
|
||||
hilog.info(TIAN_CHANNEL_DOMAIN_ID, TIAN_CHANNEL_TAG, `发送请求到: ${CHANNEL_API_CONFIG.baseUrl}/${endpoint}`);
|
||||
const response = await httpRequest.request(
|
||||
`${CHANNEL_API_CONFIG.baseUrl}/${endpoint}`,
|
||||
@ -333,12 +350,12 @@ export class ClassRoomService {
|
||||
readTimeout: CHANNEL_API_CONFIG.timeout
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
hilog.info(TIAN_CHANNEL_DOMAIN_ID, TIAN_CHANNEL_TAG, `请求完成,销毁HTTP客户端`);
|
||||
httpRequest.destroy();
|
||||
|
||||
|
||||
hilog.info(TIAN_CHANNEL_DOMAIN_ID, TIAN_CHANNEL_TAG, `响应状态码: ${response.responseCode}`);
|
||||
|
||||
|
||||
if (response.responseCode === 200) {
|
||||
try {
|
||||
hilog.info(TIAN_CHANNEL_DOMAIN_ID, TIAN_CHANNEL_TAG, `开始解析响应JSON`);
|
||||
@ -356,7 +373,7 @@ export class ClassRoomService {
|
||||
return errorResponse;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
hilog.warn(TIAN_CHANNEL_DOMAIN_ID, TIAN_CHANNEL_TAG, `HTTP错误状态码: ${response.responseCode}`);
|
||||
const errorResponse: ChannelApiResponse = {
|
||||
success: false,
|
||||
@ -367,10 +384,10 @@ export class ClassRoomService {
|
||||
// 详细记录网络错误
|
||||
const errorMsg = error instanceof Error ? error.message : String(error);
|
||||
const errorStack = error instanceof Error ? error.stack : 'No stack trace';
|
||||
|
||||
|
||||
hilog.error(TIAN_CHANNEL_DOMAIN_ID, TIAN_CHANNEL_TAG, `网络请求错误: ${errorMsg}`);
|
||||
hilog.error(TIAN_CHANNEL_DOMAIN_ID, TIAN_CHANNEL_TAG, `错误堆栈: ${errorStack}`);
|
||||
|
||||
|
||||
logManager.error(LogCategory.NETWORK, `Network request error: ${error}`);
|
||||
const errorResponse: ChannelApiResponse = {
|
||||
success: false,
|
||||
@ -379,12 +396,12 @@ export class ClassRoomService {
|
||||
return errorResponse;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 发起HTTP GET请求
|
||||
private async getRequest(endpoint: string): Promise<ChannelApiResponse> {
|
||||
try {
|
||||
const httpRequest = this.createHttpClient();
|
||||
|
||||
|
||||
const response = await httpRequest.request(
|
||||
`${CHANNEL_API_CONFIG.baseUrl}/${endpoint}`,
|
||||
{
|
||||
@ -393,9 +410,9 @@ export class ClassRoomService {
|
||||
readTimeout: CHANNEL_API_CONFIG.timeout
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
httpRequest.destroy();
|
||||
|
||||
|
||||
if (response.responseCode === 200) {
|
||||
const jsonString: string = response.result ? response.result.toString() : '{}';
|
||||
try {
|
||||
@ -410,7 +427,7 @@ export class ClassRoomService {
|
||||
return errorResponse;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const errorResponse: ChannelApiResponse = {
|
||||
success: false,
|
||||
message: `HTTP error: ${response.responseCode}`
|
||||
@ -425,15 +442,15 @@ export class ClassRoomService {
|
||||
return errorResponse;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 检查当前用户是否为教师
|
||||
public checkIsTeacher(): boolean {
|
||||
const currentAccount = settingsService.getCurrentAccount();
|
||||
hilog.info(TIAN_CHANNEL_DOMAIN_ID, TIAN_CHANNEL_TAG, `检查用户 ${currentAccount} 是否为教师`);
|
||||
|
||||
|
||||
const category = this.dbService.getUserCategory(currentAccount);
|
||||
hilog.info(TIAN_CHANNEL_DOMAIN_ID, TIAN_CHANNEL_TAG, `用户类别: ${category}`);
|
||||
|
||||
|
||||
// 首先通过数据库类别判断
|
||||
if (category === 'teacher') {
|
||||
this.isTeacher = true;
|
||||
@ -445,23 +462,23 @@ export class ClassRoomService {
|
||||
this.isTeacher = currentAccount.includes('0');
|
||||
hilog.info(TIAN_CHANNEL_DOMAIN_ID, TIAN_CHANNEL_TAG, `通过账号判断用户身份为${this.isTeacher ? '教师' : '学生'}`);
|
||||
}
|
||||
|
||||
logManager.info(LogCategory.USER, LogEventType.SYSTEM_INFO,
|
||||
|
||||
logManager.info(LogCategory.USER, LogEventType.SYSTEM_INFO,
|
||||
`用户 ${currentAccount} 的角色为: ${this.isTeacher ? '教师' : '学生'}`);
|
||||
return this.isTeacher;
|
||||
}
|
||||
|
||||
|
||||
// 启动消息轮询
|
||||
private startPolling(): void {
|
||||
if (this.pollTimerId !== -1) {
|
||||
clearInterval(this.pollTimerId);
|
||||
}
|
||||
|
||||
|
||||
this.pollTimerId = setInterval(() => {
|
||||
this.pollForUpdates();
|
||||
}, CHANNEL_API_CONFIG.pollInterval);
|
||||
}
|
||||
|
||||
|
||||
// 停止消息轮询
|
||||
private stopPolling(): void {
|
||||
if (this.pollTimerId !== -1) {
|
||||
@ -469,24 +486,24 @@ export class ClassRoomService {
|
||||
this.pollTimerId = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 轮询更新
|
||||
private async pollForUpdates(): Promise<void> {
|
||||
if (!this.connected || !this.currentClassCode) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
// 查询新消息
|
||||
const messagesResponse = await this.getRequest(`messages/${this.currentClassCode}?since=${this.lastMessageId}`);
|
||||
|
||||
|
||||
if (messagesResponse.success && messagesResponse.data && Array.isArray(messagesResponse.data)) {
|
||||
const messages = messagesResponse.data as MessageModel[];
|
||||
|
||||
|
||||
if (messages.length > 0) {
|
||||
// 更新最后接收的消息ID
|
||||
this.lastMessageId = messages[messages.length - 1].id;
|
||||
|
||||
|
||||
// 将消息添加到当前会话
|
||||
if (this.currentSession) {
|
||||
messages.forEach(message => {
|
||||
@ -499,9 +516,9 @@ export class ClassRoomService {
|
||||
this.currentSession?.messages.push(message);
|
||||
// 确保消息被添加后立即通知UI
|
||||
this.notifyEvent(WebSocketEventType.SEND_MESSAGE, message);
|
||||
|
||||
|
||||
// 记录接收到的新消息(来自他人)
|
||||
logManager.info(LogCategory.CLASS, LogEventType.SYSTEM_INFO,
|
||||
logManager.info(LogCategory.CLASS, LogEventType.SYSTEM_INFO,
|
||||
`收到新消息 - ID: ${message.id}, 发送者: ${message.senderName}, 内容: ${message.content}`);
|
||||
}
|
||||
}
|
||||
@ -509,28 +526,28 @@ export class ClassRoomService {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 查询新题目
|
||||
const questionsResponse = await this.getRequest(`questions/${this.currentClassCode}?since=${this.lastQuestionId}`);
|
||||
|
||||
|
||||
if (questionsResponse.success && questionsResponse.data && Array.isArray(questionsResponse.data)) {
|
||||
const questions = questionsResponse.data as QuestionModel[];
|
||||
|
||||
|
||||
if (questions.length > 0) {
|
||||
// 更新最后接收的题目ID
|
||||
this.lastQuestionId = questions[questions.length - 1].questionId;
|
||||
|
||||
|
||||
// 处理题目
|
||||
questions.forEach(question => {
|
||||
if (this.currentSession) {
|
||||
// 检查题目是否已存在
|
||||
const existingQuestionIndex = this.currentSession.questions.findIndex(q => q.questionId === question.questionId);
|
||||
|
||||
|
||||
if (existingQuestionIndex === -1) {
|
||||
// 新题目
|
||||
this.currentSession.questions.push(question);
|
||||
this.notifyEvent(WebSocketEventType.PUBLISH_QUESTION, question);
|
||||
|
||||
|
||||
// 如果题目处于活动状态且有结束时间,设置倒计时
|
||||
if (question.status === QuestionStatus.ACTIVE && question.duration > 0) {
|
||||
setTimeout(() => {
|
||||
@ -541,10 +558,10 @@ export class ClassRoomService {
|
||||
// 更新已有题目
|
||||
const oldQuestion = this.currentSession.questions[existingQuestionIndex];
|
||||
const oldStatus = oldQuestion.status;
|
||||
|
||||
|
||||
// 更新题目
|
||||
this.currentSession.questions[existingQuestionIndex] = question;
|
||||
|
||||
|
||||
// 如果状态从活动变为结束,通知题目结束
|
||||
if (oldStatus === QuestionStatus.ACTIVE && question.status === QuestionStatus.ENDED) {
|
||||
this.notifyEvent(WebSocketEventType.END_QUESTION, question);
|
||||
@ -554,13 +571,13 @@ export class ClassRoomService {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 查询课堂状态
|
||||
const sessionResponse = await this.getRequest(`session/${this.currentClassCode}`);
|
||||
|
||||
|
||||
if (sessionResponse.success && sessionResponse.data) {
|
||||
const session = sessionResponse.data as ClassSessionModel;
|
||||
|
||||
|
||||
// 检查课堂是否已结束
|
||||
if (session.status === ClassSessionStatus.ENDED && this.currentSession?.status === ClassSessionStatus.ACTIVE) {
|
||||
// 更新当前会话状态
|
||||
@ -568,10 +585,10 @@ export class ClassRoomService {
|
||||
this.currentSession.status = ClassSessionStatus.ENDED;
|
||||
this.currentSession.endTime = session.endTime ? new Date(session.endTime) : new Date();
|
||||
}
|
||||
|
||||
|
||||
// 通知课堂结束
|
||||
this.notifyEvent(WebSocketEventType.END_CLASS, session);
|
||||
|
||||
|
||||
// 如果不是教师,停止轮询
|
||||
if (!this.isTeacher) {
|
||||
this.disconnect();
|
||||
@ -582,33 +599,33 @@ export class ClassRoomService {
|
||||
logManager.error(LogCategory.NETWORK, `Polling error: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 检查题目状态
|
||||
private async checkQuestionStatus(questionId: string): Promise<void> {
|
||||
try {
|
||||
const response = await this.getRequest(`question/${questionId}`);
|
||||
|
||||
|
||||
if (response.success && response.data) {
|
||||
const question = response.data as QuestionModel;
|
||||
|
||||
|
||||
// 如果题目仍处于活动状态,结束题目
|
||||
if (question.status === QuestionStatus.ACTIVE && this.currentSession) {
|
||||
// 查找并更新本地题目
|
||||
const questionIndex = this.currentSession.questions.findIndex(q => q.questionId === questionId);
|
||||
|
||||
|
||||
if (questionIndex !== -1) {
|
||||
// 更新题目状态
|
||||
this.currentSession.questions[questionIndex].status = QuestionStatus.ENDED;
|
||||
this.currentSession.questions[questionIndex].endTime = new Date();
|
||||
|
||||
|
||||
// 提交题目状态更新
|
||||
const request: EndQuestionRequest = {
|
||||
questionId: questionId,
|
||||
classCode: this.currentClassCode
|
||||
};
|
||||
|
||||
|
||||
await this.postRequest('endQuestion', request);
|
||||
|
||||
|
||||
// 通知题目结束
|
||||
this.notifyEvent(WebSocketEventType.END_QUESTION, this.currentSession.questions[questionIndex]);
|
||||
}
|
||||
@ -618,15 +635,15 @@ export class ClassRoomService {
|
||||
logManager.error(LogCategory.CLASS, `Error checking question status: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 连接服务
|
||||
public async connect(): Promise<boolean> {
|
||||
if (this.connected) return true;
|
||||
|
||||
|
||||
try {
|
||||
// 验证服务器连接
|
||||
const response = await this.getRequest('ping');
|
||||
|
||||
|
||||
if (response.success) {
|
||||
this.connected = true;
|
||||
const connectionEvent: EventConnection = { status: 'connected' };
|
||||
@ -642,23 +659,23 @@ export class ClassRoomService {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 断开连接
|
||||
public disconnect(): void {
|
||||
if (!this.connected) return;
|
||||
|
||||
|
||||
// 停止轮询
|
||||
this.stopPolling();
|
||||
|
||||
|
||||
this.connected = false;
|
||||
this.notifyEvent('connection', { status: 'disconnected' });
|
||||
logManager.info(LogCategory.NETWORK, LogEventType.SYSTEM_INFO, 'Channel service disconnected');
|
||||
|
||||
|
||||
// 清空当前会话
|
||||
this.currentSession = null;
|
||||
this.currentClassCode = '';
|
||||
}
|
||||
|
||||
|
||||
// 创建新课堂(教师)
|
||||
public async createClassSession(className: string, classCode: string): Promise<ClassSessionModel | null> {
|
||||
try {
|
||||
@ -669,23 +686,23 @@ export class ClassRoomService {
|
||||
teacherAccount: settingsService.getCurrentAccount(),
|
||||
teacherName: settingsService.getUserNickname()
|
||||
};
|
||||
|
||||
|
||||
const response = await this.postRequest('createSession', reqData);
|
||||
|
||||
|
||||
if (response.success && response.data) {
|
||||
// 设置当前会话
|
||||
this.currentSession = response.data as ClassSessionModel;
|
||||
this.currentClassCode = classCode;
|
||||
this.isTeacher = true;
|
||||
this.connected = true;
|
||||
|
||||
|
||||
// 开始消息轮询
|
||||
this.startPolling();
|
||||
|
||||
|
||||
// 通知连接状态
|
||||
const connectionEvent: EventConnection = { status: 'connected' };
|
||||
this.notifyEvent(WebSocketEventType.JOIN_CLASS, connectionEvent);
|
||||
|
||||
|
||||
return this.currentSession;
|
||||
} else {
|
||||
logManager.error(LogCategory.CLASS, `Create session failed: ${response.message}`);
|
||||
@ -696,7 +713,7 @@ export class ClassRoomService {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 加入课堂(学生)
|
||||
public async joinClassSession(classCode: string): Promise<boolean> {
|
||||
try {
|
||||
@ -706,23 +723,23 @@ export class ClassRoomService {
|
||||
studentAccount: settingsService.getCurrentAccount(),
|
||||
studentName: settingsService.getUserNickname()
|
||||
};
|
||||
|
||||
|
||||
const response = await this.postRequest('joinSession', reqData);
|
||||
|
||||
|
||||
if (response.success && response.data) {
|
||||
// 设置当前会话
|
||||
this.currentSession = response.data as ClassSessionModel;
|
||||
this.currentClassCode = classCode;
|
||||
this.isTeacher = false;
|
||||
this.connected = true;
|
||||
|
||||
|
||||
// 开始消息轮询
|
||||
this.startPolling();
|
||||
|
||||
|
||||
// 通知连接状态
|
||||
const connectionEvent: EventConnection = { status: 'connected' };
|
||||
this.notifyEvent(WebSocketEventType.JOIN_CLASS, connectionEvent);
|
||||
|
||||
|
||||
return true;
|
||||
} else {
|
||||
logManager.error(LogCategory.CLASS, `Join session failed: ${response.message}`);
|
||||
@ -733,11 +750,11 @@ export class ClassRoomService {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 发送消息
|
||||
public async sendMessage(content: string): Promise<boolean> {
|
||||
hilog.info(TIAN_CHANNEL_DOMAIN_ID, TIAN_CHANNEL_TAG, `========= 开始发送消息 =========`);
|
||||
|
||||
|
||||
// 检查前提条件
|
||||
if (!this.currentSession) {
|
||||
hilog.error(TIAN_CHANNEL_DOMAIN_ID, TIAN_CHANNEL_TAG, `发送失败: currentSession为空`);
|
||||
@ -751,52 +768,52 @@ export class ClassRoomService {
|
||||
hilog.error(TIAN_CHANNEL_DOMAIN_ID, TIAN_CHANNEL_TAG, `发送失败: currentClassCode为空`);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (!this.currentSession || !this.connected || !this.currentClassCode) {
|
||||
logManager.error(LogCategory.CLASS, `Cannot send message: No active session or not connected`);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Debug message: Log session and connection information
|
||||
hilog.info(TIAN_CHANNEL_DOMAIN_ID, TIAN_CHANNEL_TAG, `会话ID: ${this.currentSession.sessionId}`);
|
||||
hilog.info(TIAN_CHANNEL_DOMAIN_ID, TIAN_CHANNEL_TAG, `课堂码: ${this.currentClassCode}`);
|
||||
hilog.info(TIAN_CHANNEL_DOMAIN_ID, TIAN_CHANNEL_TAG, `连接状态: ${this.connected}`);
|
||||
|
||||
|
||||
logManager.info(LogCategory.CLASS, LogEventType.SYSTEM_INFO, `[DEBUG] Message sending attempt - Session ID: ${this.currentSession.sessionId}, Class Code: ${this.currentClassCode}, Connection status: ${this.connected}`);
|
||||
|
||||
|
||||
// 获取用户信息
|
||||
hilog.info(TIAN_CHANNEL_DOMAIN_ID, TIAN_CHANNEL_TAG, `获取用户信息`);
|
||||
const currentAccount = settingsService.getCurrentAccount();
|
||||
const senderName = this.dbService.getUserNickname(currentAccount) || currentAccount;
|
||||
const role = this.isTeacher ? SenderRole.TEACHER : SenderRole.STUDENT;
|
||||
|
||||
|
||||
hilog.info(TIAN_CHANNEL_DOMAIN_ID, TIAN_CHANNEL_TAG, `用户账号: ${currentAccount}`);
|
||||
hilog.info(TIAN_CHANNEL_DOMAIN_ID, TIAN_CHANNEL_TAG, `用户名称: ${senderName}`);
|
||||
hilog.info(TIAN_CHANNEL_DOMAIN_ID, TIAN_CHANNEL_TAG, `用户角色: ${role}`);
|
||||
|
||||
|
||||
// Debug message: Log user information
|
||||
logManager.info(LogCategory.CLASS, LogEventType.SYSTEM_INFO, `[DEBUG] Message sender info - Account: ${currentAccount}, Name: ${senderName}, Role: ${role}`);
|
||||
|
||||
|
||||
// 创建消息对象
|
||||
hilog.info(TIAN_CHANNEL_DOMAIN_ID, TIAN_CHANNEL_TAG, `创建消息对象`);
|
||||
try {
|
||||
// 单独记录消息创建过程
|
||||
hilog.info(TIAN_CHANNEL_DOMAIN_ID, TIAN_CHANNEL_TAG, `消息内容: ${content}`);
|
||||
|
||||
|
||||
const message = new MessageModel(currentAccount, senderName, role, content);
|
||||
|
||||
|
||||
hilog.info(TIAN_CHANNEL_DOMAIN_ID, TIAN_CHANNEL_TAG, `消息创建成功,ID: ${message.id}`);
|
||||
hilog.info(TIAN_CHANNEL_DOMAIN_ID, TIAN_CHANNEL_TAG, `消息时间戳: ${message.timestamp.toISOString()}`);
|
||||
|
||||
|
||||
logManager.info(LogCategory.CLASS, LogEventType.SYSTEM_INFO, `Creating message: ID=${message.id}, Content=${content}, Sender=${senderName}, Role=${role}`);
|
||||
|
||||
|
||||
// 构建请求
|
||||
hilog.info(TIAN_CHANNEL_DOMAIN_ID, TIAN_CHANNEL_TAG, `构建发送请求`);
|
||||
const request: SendMessageRequest = {
|
||||
classCode: this.currentClassCode,
|
||||
message: message
|
||||
};
|
||||
|
||||
|
||||
// 打印请求对象,但避免过长内容
|
||||
let requestStr = "";
|
||||
try {
|
||||
@ -805,49 +822,49 @@ export class ClassRoomService {
|
||||
} catch (e) {
|
||||
hilog.error(TIAN_CHANNEL_DOMAIN_ID, TIAN_CHANNEL_TAG, `无法序列化请求: ${e}`);
|
||||
}
|
||||
|
||||
|
||||
logManager.info(LogCategory.CLASS, LogEventType.SYSTEM_INFO, `发送消息请求: classCode=${this.currentClassCode}, messageId=${message.id}`);
|
||||
|
||||
|
||||
// 发送请求
|
||||
hilog.info(TIAN_CHANNEL_DOMAIN_ID, TIAN_CHANNEL_TAG, `开始发送POST请求到sendMessage`);
|
||||
const response = await this.postRequest('sendMessage', request);
|
||||
hilog.info(TIAN_CHANNEL_DOMAIN_ID, TIAN_CHANNEL_TAG, `请求完成,响应success: ${response.success}`);
|
||||
|
||||
|
||||
// 详细记录响应
|
||||
if (response.message) {
|
||||
hilog.info(TIAN_CHANNEL_DOMAIN_ID, TIAN_CHANNEL_TAG, `响应消息: ${response.message}`);
|
||||
}
|
||||
if (response.data) {
|
||||
try {
|
||||
const dataStr = JSON.stringify(response.data).substring(0, 100) +
|
||||
const dataStr = JSON.stringify(response.data).substring(0, 100) +
|
||||
(JSON.stringify(response.data).length > 100 ? '...' : '');
|
||||
hilog.info(TIAN_CHANNEL_DOMAIN_ID, TIAN_CHANNEL_TAG, `响应数据(摘要): ${dataStr}`);
|
||||
} catch (e) {
|
||||
hilog.error(TIAN_CHANNEL_DOMAIN_ID, TIAN_CHANNEL_TAG, `无法序列化响应数据: ${e}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
logManager.info(LogCategory.CLASS, LogEventType.SYSTEM_INFO, `服务器响应: success=${response.success}, message=${response.message || "无"}`);
|
||||
|
||||
|
||||
if (response.success) {
|
||||
hilog.info(TIAN_CHANNEL_DOMAIN_ID, TIAN_CHANNEL_TAG, `消息发送成功,更新lastMessageId: ${message.id}`);
|
||||
// 不再将消息添加到currentSession,因为UI层已经添加了本地消息
|
||||
// (已删除): this.currentSession.messages.push(message);
|
||||
|
||||
// (已删除): this.currentSession.messages.push(message);
|
||||
|
||||
// 不需要再次通知UI,因为UI层已经添加了本地消息
|
||||
// (已删除): this.notifyEvent(WebSocketEventType.SEND_MESSAGE, message);
|
||||
|
||||
|
||||
// 只添加到lastMessageId,确保轮询时不重复获取
|
||||
this.lastMessageId = message.id;
|
||||
|
||||
|
||||
logManager.info(LogCategory.CLASS, LogEventType.SYSTEM_INFO, `Message sent successfully: ${message.id}`);
|
||||
hilog.info(TIAN_CHANNEL_DOMAIN_ID, TIAN_CHANNEL_TAG, `========= 消息发送成功 =========`);
|
||||
|
||||
|
||||
return true;
|
||||
} else {
|
||||
// Enhanced error logging with response details
|
||||
hilog.error(TIAN_CHANNEL_DOMAIN_ID, TIAN_CHANNEL_TAG, `消息发送失败: ${response.message || '未知错误'}`);
|
||||
logManager.error(LogCategory.CLASS, `Send message failed: ${response.message || 'Unknown error'}, Response data: ${JSON.stringify(response.data || {})}`);
|
||||
logManager.error(LogCategory.CLASS, `Send message failed: ${response.message || 'Unknown error'}, Response data: ${JSON.stringify(response.data)}`);
|
||||
hilog.info(TIAN_CHANNEL_DOMAIN_ID, TIAN_CHANNEL_TAG, `========= 消息发送失败 =========`);
|
||||
return false;
|
||||
}
|
||||
|
@ -14,13 +14,13 @@ export class UserModel {
|
||||
phone: string = '';
|
||||
photo: string = '';
|
||||
category: string = '';
|
||||
|
||||
constructor(account: string = '',
|
||||
nickname: string = '',
|
||||
email: string = '',
|
||||
phone: string = '',
|
||||
photo: string = '',
|
||||
category: string = '') {
|
||||
|
||||
constructor(account: string = '',
|
||||
nickname: string = '',
|
||||
email: string = '',
|
||||
phone: string = '',
|
||||
photo: string = '',
|
||||
category: string = '') {
|
||||
this.account = account;
|
||||
this.nickname = nickname;
|
||||
this.email = email;
|
||||
@ -51,13 +51,16 @@ export interface UserInfo {
|
||||
export interface ApiConfig {
|
||||
baseUrl: string;
|
||||
timeout: number;
|
||||
websocketDomain: string
|
||||
}
|
||||
|
||||
// 定义API服务配置
|
||||
const API_CONFIG: ApiConfig = {
|
||||
// 修改为用户实际使用的服务器地址
|
||||
baseUrl: 'http://139.155.155.67:2342/api',
|
||||
timeout: 10000 // 10秒超时
|
||||
timeout: 10000, // 10秒超时
|
||||
websocketDomain: "139.155.155.67:4233",
|
||||
// websocketDomain: "198.18.0.1:8080",
|
||||
};
|
||||
|
||||
// 修正JSON响应类型处理
|
||||
@ -79,23 +82,26 @@ export class DatabaseService {
|
||||
// 缓存用户数据,减少API调用
|
||||
private userCache: Map<string, UserModel> = new Map();
|
||||
// 缓存验证结果
|
||||
private authCache: Map<string, boolean> = new Map();
|
||||
|
||||
private authCache: Map<string, boolean> = new Map();
|
||||
// Callbacks for user data changes
|
||||
private userDataChangeCallbacks: (() => void)[] = [];
|
||||
|
||||
|
||||
private constructor() {
|
||||
// 初始化缓存
|
||||
hilog.info(0, 'ClassMG', 'Database Service Initialized');
|
||||
}
|
||||
|
||||
|
||||
public static getInstance(): DatabaseService {
|
||||
if (!DatabaseService.instance) {
|
||||
DatabaseService.instance = new DatabaseService();
|
||||
}
|
||||
return DatabaseService.instance;
|
||||
}
|
||||
|
||||
|
||||
public static getApiConfig():ApiConfig{
|
||||
return API_CONFIG;
|
||||
}
|
||||
|
||||
// 创建HTTP请求客户端
|
||||
private createHttpClient(): http.HttpRequest {
|
||||
let httpRequest = http.createHttp();
|
||||
@ -104,27 +110,27 @@ export class DatabaseService {
|
||||
});
|
||||
return httpRequest;
|
||||
}
|
||||
|
||||
|
||||
// 执行登录验证
|
||||
public async validateUser(account: string, password: string): Promise<boolean> {
|
||||
try {
|
||||
// 生成缓存键
|
||||
const cacheKey = `${account}:${password}`;
|
||||
|
||||
|
||||
// 检查缓存
|
||||
if (this.authCache.has(cacheKey)) {
|
||||
const cachedResult = this.authCache.get(cacheKey);
|
||||
return cachedResult === true; // 确保返回布尔值
|
||||
}
|
||||
|
||||
|
||||
// 创建HTTP客户端
|
||||
const httpRequest = this.createHttpClient();
|
||||
|
||||
|
||||
// 准备登录数据
|
||||
let loginData = {} as Record<string, string>;
|
||||
loginData.account = account;
|
||||
loginData.password = password;
|
||||
|
||||
|
||||
// 发送登录请求
|
||||
const response = await httpRequest.request(
|
||||
`${API_CONFIG.baseUrl}/login`,
|
||||
@ -138,21 +144,21 @@ export class DatabaseService {
|
||||
readTimeout: API_CONFIG.timeout
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
// 释放HTTP客户端
|
||||
httpRequest.destroy();
|
||||
|
||||
|
||||
// 检查响应
|
||||
if (response.responseCode === 200) {
|
||||
// 使用显式类型转换处理JSON结果
|
||||
const jsonString: string = response.result ? response.result.toString() : '{}';
|
||||
try {
|
||||
const result: ApiResponse = JSON.parse(jsonString) as ApiResponse;
|
||||
|
||||
|
||||
// 缓存结果
|
||||
const isValid = result.success === true;
|
||||
this.authCache.set(cacheKey, isValid);
|
||||
|
||||
|
||||
// 如果登录成功且有用户数据,缓存用户信息
|
||||
if (isValid && result.user) {
|
||||
const user = new UserModel(
|
||||
@ -165,28 +171,28 @@ export class DatabaseService {
|
||||
);
|
||||
this.userCache.set(account, user);
|
||||
}
|
||||
|
||||
|
||||
return isValid;
|
||||
} catch (parseError) {
|
||||
const errorMsg: string = parseError instanceof Error ? parseError.message : String(parseError);
|
||||
hilog.error(0, 'ClassMG', `Error parsing JSON response: ${errorMsg}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 默认返回false
|
||||
return false;
|
||||
} catch (error) {
|
||||
hilog.error(0, 'ClassMG', `Error validating user: ${error instanceof Error ? error.message : String(error)}`);
|
||||
|
||||
|
||||
// 临时降级到模拟验证 - 仅用于开发/测试
|
||||
/* if (account === '2' || account === '9222' || account === '0') {
|
||||
return password === '1';
|
||||
}
|
||||
*/
|
||||
/* if (account === '2' || account === '9222' || account === '0') {
|
||||
return password === '1';
|
||||
}
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 获取用户类别
|
||||
public getUserCategory(account: string): string {
|
||||
// 检查缓存
|
||||
@ -194,17 +200,17 @@ export class DatabaseService {
|
||||
const user = this.userCache.get(account);
|
||||
return user ? user.category : '';
|
||||
}
|
||||
|
||||
|
||||
// 降级逻辑 - 当API不可用时
|
||||
if (account.includes('2')) {
|
||||
return 'student';
|
||||
} else if (account.includes('0')) {
|
||||
return 'teacher';
|
||||
}
|
||||
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
// 获取用户昵称
|
||||
public getUserNickname(account: string): string {
|
||||
// 检查缓存
|
||||
@ -212,15 +218,21 @@ export class DatabaseService {
|
||||
const user = this.userCache.get(account);
|
||||
return user ? user.nickname : '';
|
||||
}
|
||||
|
||||
|
||||
// 默认值 - 仅用于开发/测试
|
||||
if (account === '2') return '张三';
|
||||
if (account === '9222') return '李华';
|
||||
if (account === '0') return '教师demo';
|
||||
|
||||
if (account === '2') {
|
||||
return '张三';
|
||||
}
|
||||
if (account === '9222') {
|
||||
return '李华';
|
||||
}
|
||||
if (account === '0') {
|
||||
return '教师demo';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
// 异步获取用户信息
|
||||
public async getUserByAccountAsync(account: string): Promise<UserModel | null> {
|
||||
try {
|
||||
@ -229,10 +241,10 @@ export class DatabaseService {
|
||||
const cachedUser = this.userCache.get(account);
|
||||
return cachedUser || null;
|
||||
}
|
||||
|
||||
|
||||
// 创建HTTP客户端
|
||||
const httpRequest = this.createHttpClient();
|
||||
|
||||
|
||||
// 发送获取用户信息请求
|
||||
const response = await httpRequest.request(
|
||||
`${API_CONFIG.baseUrl}/user/${account}`,
|
||||
@ -242,17 +254,17 @@ export class DatabaseService {
|
||||
readTimeout: API_CONFIG.timeout
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
// 释放HTTP客户端
|
||||
httpRequest.destroy();
|
||||
|
||||
|
||||
// 检查响应
|
||||
if (response.responseCode === 200) {
|
||||
// 使用显式类型转换处理JSON结果
|
||||
const jsonString: string = response.result ? response.result.toString() : '{}';
|
||||
try {
|
||||
const result: ApiResponse = JSON.parse(jsonString) as ApiResponse;
|
||||
|
||||
|
||||
if (result.success && result.user) {
|
||||
const user = new UserModel(
|
||||
result.user.account,
|
||||
@ -262,10 +274,10 @@ export class DatabaseService {
|
||||
result.user.photo,
|
||||
result.user.category
|
||||
);
|
||||
|
||||
|
||||
// 更新缓存
|
||||
this.userCache.set(account, user);
|
||||
|
||||
|
||||
return user;
|
||||
}
|
||||
} catch (parseError) {
|
||||
@ -273,24 +285,24 @@ export class DatabaseService {
|
||||
hilog.error(0, 'ClassMG', `Error parsing JSON response: ${errorMsg}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
} catch (error) {
|
||||
hilog.error(0, 'ClassMG', `Error getting user: ${error instanceof Error ? error.message : String(error)}`);
|
||||
|
||||
|
||||
// 降级到模拟数据 - 仅用于开发/测试
|
||||
/* if (account === '2') {
|
||||
return new UserModel('2', '张三', 'student@qq.com', '17267383831', '', 'student');
|
||||
} else if (account === '9222') {
|
||||
return new UserModel('9222', '李华', 'student123@qq.com', '12345678901', '', 'student');
|
||||
} else if (account === '0') {
|
||||
return new UserModel('0', '教师demo', 'teach@qq.com', '', '', 'teacher');
|
||||
}*/
|
||||
|
||||
/* if (account === '2') {
|
||||
return new UserModel('2', '张三', 'student@qq.com', '17267383831', '', 'student');
|
||||
} else if (account === '9222') {
|
||||
return new UserModel('9222', '李华', 'student123@qq.com', '12345678901', '', 'student');
|
||||
} else if (account === '0') {
|
||||
return new UserModel('0', '教师demo', 'teach@qq.com', '', '', 'teacher');
|
||||
}*/
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 为了兼容性保留的同步方法 - 使用缓存
|
||||
public getUserByAccount(account: string): UserModel | null {
|
||||
// 检查缓存
|
||||
@ -298,7 +310,7 @@ export class DatabaseService {
|
||||
const cachedUser = this.userCache.get(account);
|
||||
return cachedUser || null;
|
||||
}
|
||||
|
||||
|
||||
// 如果缓存中没有,返回null并触发异步加载
|
||||
this.getUserByAccountAsync(account)
|
||||
.then((user: UserModel | null) => {
|
||||
@ -310,10 +322,10 @@ export class DatabaseService {
|
||||
const errorMsg: string = error instanceof Error ? error.message : String(error);
|
||||
hilog.error(0, 'ClassMG', `Error in async user fetch: ${errorMsg}`);
|
||||
});
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// 更新用户邮箱 - 连接API
|
||||
public async updateUserEmail(account: string, newEmail: string): Promise<boolean> {
|
||||
try {
|
||||
@ -321,14 +333,14 @@ export class DatabaseService {
|
||||
if (!this.validateEmailFormat(newEmail)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// 创建HTTP客户端
|
||||
const httpRequest = this.createHttpClient();
|
||||
|
||||
|
||||
// 准备更新数据
|
||||
let updateData = {} as Record<string, string>;
|
||||
updateData.email = newEmail;
|
||||
|
||||
|
||||
// 发送更新请求
|
||||
const response = await httpRequest.request(
|
||||
`${API_CONFIG.baseUrl}/user/${account}/email`,
|
||||
@ -342,17 +354,17 @@ export class DatabaseService {
|
||||
readTimeout: API_CONFIG.timeout
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
// 释放HTTP客户端
|
||||
httpRequest.destroy();
|
||||
|
||||
|
||||
// 检查响应
|
||||
if (response.responseCode === 200) {
|
||||
// 使用显式类型转换处理JSON结果
|
||||
const jsonString: string = response.result ? response.result.toString() : '{}';
|
||||
try {
|
||||
const result: ApiResponse = JSON.parse(jsonString) as ApiResponse;
|
||||
|
||||
|
||||
if (result.success) {
|
||||
// 更新本地缓存
|
||||
if (this.userCache.has(account)) {
|
||||
@ -362,10 +374,10 @@ export class DatabaseService {
|
||||
this.userCache.set(account, user);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 通知更新
|
||||
this.notifyUserDataChange();
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
} catch (parseError) {
|
||||
@ -373,12 +385,12 @@ export class DatabaseService {
|
||||
hilog.error(0, 'ClassMG', `Error parsing JSON response: ${errorMsg}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
} catch (error) {
|
||||
const errorMessage: string = error instanceof Error ? error.message : String(error);
|
||||
hilog.error(0, 'ClassMG', `Error updating user email: ${errorMessage}`);
|
||||
|
||||
|
||||
// 降级到本地更新 - 仅用于开发/测试
|
||||
if (this.userCache.has(account)) {
|
||||
const user = this.userCache.get(account);
|
||||
@ -389,41 +401,41 @@ export class DatabaseService {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 注册数据变化回调
|
||||
public registerUserDataChangeCallback(callback: () => void): void {
|
||||
this.userDataChangeCallbacks.push(callback);
|
||||
}
|
||||
|
||||
|
||||
// 通知所有回调
|
||||
private notifyUserDataChange(): void {
|
||||
this.userDataChangeCallbacks.forEach(callback => {
|
||||
callback();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// 验证邮箱格式
|
||||
public validateEmailFormat(email: string): boolean {
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
return emailRegex.test(email);
|
||||
}
|
||||
|
||||
|
||||
// 清除缓存
|
||||
public clearCache(): void {
|
||||
this.userCache.clear();
|
||||
this.authCache.clear();
|
||||
}
|
||||
|
||||
|
||||
// 注册用户
|
||||
public async registerUser(userData: RegisterUserData): Promise<boolean> {
|
||||
try {
|
||||
// 创建HTTP客户端
|
||||
const httpRequest = this.createHttpClient();
|
||||
|
||||
|
||||
// 发送注册请求
|
||||
const response = await httpRequest.request(
|
||||
`${API_CONFIG.baseUrl}/register`,
|
||||
@ -437,10 +449,10 @@ export class DatabaseService {
|
||||
readTimeout: API_CONFIG.timeout
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
// 释放HTTP客户端
|
||||
httpRequest.destroy();
|
||||
|
||||
|
||||
// 检查响应
|
||||
if (response.responseCode === 200) {
|
||||
// 使用显式类型转换处理JSON结果
|
||||
@ -453,7 +465,7 @@ export class DatabaseService {
|
||||
hilog.error(0, 'ClassMG', `Error parsing JSON response: ${errorMsg}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
} catch (error) {
|
||||
hilog.error(0, 'ClassMG', `Error registering user: ${error instanceof Error ? error.message : String(error)}`);
|
||||
|
@ -20,6 +20,9 @@ import {
|
||||
import logManager, { LogCategory, LogEventType } from '../common/logtext';
|
||||
import http from '@ohos.net.http';
|
||||
import hilog from '@ohos.hilog';
|
||||
import WebSocketMessage from '../util/WebsocketMessage';
|
||||
import { BusinessError } from '@kit.BasicServicesKit';
|
||||
import { DatabaseService } from '../common/DatabaseService';
|
||||
|
||||
// 添加hilog和tianChannel常量
|
||||
const TIAN_CHANNEL_DOMAIN_ID = 0x00201; // 自定义域ID
|
||||
@ -133,8 +136,11 @@ struct ClassLivePage {
|
||||
};
|
||||
// 用于服务实例
|
||||
private classRoomService: ClassRoomService = ClassRoomService.getInstance();
|
||||
wsClient: WebSocketMessage = new WebSocketMessage(DatabaseService.getApiConfig().websocketDomain, "111111")
|
||||
|
||||
aboutToAppear() {
|
||||
this.wsClient.connect();
|
||||
|
||||
// 注册语言变化的回调
|
||||
settingsService.registerLanguageChangeCallback(() => {
|
||||
this.texts = settingsService.getTextResources();
|
||||
@ -170,6 +176,19 @@ struct ClassLivePage {
|
||||
this.registerEventListeners();
|
||||
|
||||
logManager.info(LogCategory.CLASS, LogEventType.PAGE_APPEAR, 'ClassLivePage');
|
||||
|
||||
|
||||
this.wsClient.setOnMessage((data) => {
|
||||
hilog.debug(TIAN_CHANNEL_DOMAIN_ID, TIAN_CHANNEL_TAG, "收到消息: " + data.toString());
|
||||
try {
|
||||
let j: MessageModel = MessageModel.fromJSON(data.toString()) //JSON.parse(data.toString()) as MessageModel
|
||||
this.messages.push(j)
|
||||
hilog.debug(TIAN_CHANNEL_DOMAIN_ID, TIAN_CHANNEL_TAG, "渲染: " + j);
|
||||
// this.messages.push(data.toString())
|
||||
} catch (e) {
|
||||
hilog.debug(TIAN_CHANNEL_DOMAIN_ID, TIAN_CHANNEL_TAG, "消息解析失败: " + e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 注册事件监听
|
||||
@ -177,6 +196,7 @@ struct ClassLivePage {
|
||||
// 接收新消息
|
||||
this.messageCallback = (data: EventData) => {
|
||||
const message = data as MessageModel;
|
||||
message.useTime()
|
||||
if (message && message.id) {
|
||||
// 检查消息是否已经存在(防止重复)
|
||||
const existingMessage = this.messages.find(m => m.id === message.id);
|
||||
|
81
entry/src/main/ets/util/WebsocketMessage.ets
Normal file
81
entry/src/main/ets/util/WebsocketMessage.ets
Normal file
@ -0,0 +1,81 @@
|
||||
import { webSocket } from "@kit.NetworkKit";
|
||||
import { BusinessError } from "@kit.BasicServicesKit";
|
||||
import { hilog } from "@kit.PerformanceAnalysisKit";
|
||||
|
||||
const DOMAIN: number = 0
|
||||
const TAG: string = "websocket message"
|
||||
|
||||
export default class WebSocketMessage {
|
||||
private ws = webSocket.createWebSocket();
|
||||
private url: string;
|
||||
private room: string;
|
||||
private onMessageCallback: (data: string | ArrayBuffer) => void = () => {
|
||||
};
|
||||
|
||||
constructor(url: string, room: string) {
|
||||
this.url = url;
|
||||
this.room = room;
|
||||
}
|
||||
|
||||
public connect(): void {
|
||||
this.ws.on('open', (err: BusinessError, value: Object) => {
|
||||
hilog.debug(DOMAIN, TAG, "on open, status: " + JSON.stringify(value));
|
||||
this.ws.send("Hello, server!", (err: BusinessError, success: boolean) => {
|
||||
if (!err) {
|
||||
hilog.debug(DOMAIN, TAG, "Message sent successfully");
|
||||
} else {
|
||||
hilog.debug(DOMAIN, TAG, "Failed to send the message. Err: " + JSON.stringify(err));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
this.ws.on('message', (err: BusinessError, value: string | ArrayBuffer) => {
|
||||
hilog.debug(DOMAIN, TAG, "on message, message: " + value);
|
||||
if (value === 'bye') {
|
||||
this.close();
|
||||
}
|
||||
this.onMessageCallback(value);
|
||||
});
|
||||
|
||||
this.ws.on('close', (err: BusinessError, value: webSocket.CloseResult) => {
|
||||
hilog.debug(DOMAIN, TAG, "on close, code: " + value.code + ", reason: " + value.reason);
|
||||
});
|
||||
|
||||
this.ws.on('error', (err: BusinessError) => {
|
||||
hilog.debug(DOMAIN, TAG, "on error, error: " + JSON.stringify(err));
|
||||
});
|
||||
|
||||
const wsUrl = `ws://${this.url}/ws/room?room=${this.room}`;
|
||||
this.ws.connect(wsUrl, (err: BusinessError, connected: boolean) => {
|
||||
if (!err) {
|
||||
hilog.debug(DOMAIN, TAG, "Connected successfully");
|
||||
} else {
|
||||
hilog.debug(DOMAIN, TAG, "Connection failed. Err: " + JSON.stringify(err));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public setOnMessage(callback: (data: string | ArrayBuffer) => void): void {
|
||||
this.onMessageCallback = callback;
|
||||
}
|
||||
|
||||
public sendMessage(message: string): void {
|
||||
this.ws.send(message, (err: BusinessError, success: boolean) => {
|
||||
if (!err) {
|
||||
hilog.debug(DOMAIN, TAG, "Message sent: " + message);
|
||||
} else {
|
||||
hilog.debug(DOMAIN, TAG, "Send failed: " + JSON.stringify(err));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public close(): void {
|
||||
this.ws.close((err: BusinessError, success: boolean) => {
|
||||
if (!err) {
|
||||
hilog.debug(DOMAIN, TAG, "Connection closed successfully");
|
||||
} else {
|
||||
hilog.debug(DOMAIN, TAG, "Failed to close the connection. Err: " + JSON.stringify(err));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user