receive message live

This commit is contained in:
Peter Maquiran
2024-07-16 14:15:58 +01:00
parent 4a1db73402
commit 0312df88e8
12 changed files with 157 additions and 28 deletions
+1 -1
View File
@@ -16,7 +16,7 @@
"path": "../grayLog"
},
{
"path": "../../../Downloads/equilibriumito-gabinete-digital-fo-4f51cb55504b"
"path": "../../../Downloads/equilibriumito-gabinete-digital-fo-23cf0fc4cbaa/equilibriumito-gabinete-digital-fo-23cf0fc4cbaa"
}
],
"settings": {
@@ -1,10 +1,12 @@
import { Injectable } from '@angular/core';
import { MessageLiveDataSourceService } from '../../data-source/message/message-live-data-source.service';
import { MessageLocalDataSourceService } from '../../data-source/message/message-local-data-source.service';
import { IncomingMessageSchema, MessageLocalDataSourceService } from '../../data-source/message/message-local-data-source.service';
import { MessageRemoteDataSourceService } from '../../data-source/message/message-remote-data-source.service';
import { SignalRService } from '../../../infra/socket/signal-r.service';
import { filter } from 'rxjs/operators';
import { InstanceId } from '../../repository/message-respository.service';
import { SocketStreamReturn } from 'src/app/services/decorators/socket-validate-schema.decorator';
import { SafeValidateSchema } from 'src/app/services/decorators/validate-schema.decorator';
@Injectable({
providedIn: 'root'
@@ -26,25 +28,33 @@ export class MessageAsyncService {
).subscribe(async (message: any) => {
console.log('message async ', message)
const id = message.id
const id = message.id + ''
delete message.id;
const result = await this.messageLocalDataSourceService.createMessage({
const incomingMessage = {
...message,
messageId: id,
sending: false,
...message
})
if(result.isOk()) {
console.log(result.value)
console.log("nice send receive")
} else {
console.log(result.error)
roomId:message.chatRoomId
}
this.incomingMessage(incomingMessage)
})
}
@SafeValidateSchema(IncomingMessageSchema, 'socket/incomingMessage')
async incomingMessage(IncomingMessageSchema: any) {
const result = await this.messageLocalDataSourceService.sendMessage(IncomingMessageSchema)
if(result.isOk()) {
} else {
console.log(result.error)
}
}
}
@@ -11,7 +11,24 @@ const tableSchema = z.object({
id: z.any().optional(),
messageId: z.string().optional(),
roomId: z.string().uuid(),
senderId: z.number(),
message: z.string(),
messageType: z.number(),
canEdit: z.boolean(),
oneShot: z.boolean(),
sentAt: z.string().optional(),
requireUnlock: z.boolean(),
sender: z.object({
wxUserId: z.number(),
wxFullName: z.string(),
wxeMail: z.string(),
userPhoto: z.string(),
}),
sending: z.boolean().optional()
})
export const IncomingMessageSchema = z.object({
messageId: z.string().optional(),
roomId: z.string().uuid(),
message: z.string(),
messageType: z.number(),
canEdit: z.boolean(),
@@ -36,7 +53,7 @@ export const messageDataSource = new Dexie('chat-message') as Dexie & {
};
messageDataSource.version(1).stores({
message: '++id, roomId, senderId, message, messageType, canEdit, oneShot, requireUnlock, messageId'
message: '++id, roomId, message, messageType, canEdit, oneShot, requireUnlock, messageId'
});
@Injectable({
@@ -6,6 +6,7 @@ import { MessageLocalDataSourceService, TableMessage } from '../data-source/mess
import { SessionStore } from 'src/app/store/session.service';
import { SignalRService } from '../../infra/socket/signal-r.service';
import { v4 as uuidv4 } from 'uuid'
import { filter } from 'rxjs/operators';
export const InstanceId = uuidv4();
@@ -43,7 +43,7 @@ export class SignalRService {
private async establishConnection() {
const connection = new SignalRConnection({url:'https://gdapi-dev.dyndns.info/stage/chathub'})
const connection = new SignalRConnection({url:'https://gdapi-dev.dyndns.info/stage/api/v2/chathub'})
const attempConnection = await connection.establishConnection()
if(attempConnection.isOk()) {
+1 -1
View File
@@ -20,7 +20,7 @@
const connection = new signalR.HubConnectionBuilder()
.withAutomaticReconnect()
.withUrl("https://gdapi-dev.dyndns.info/stage/chathub")
.withUrl("https://gdapi-dev.dyndns.info/stage/api/v2/chathub")
.build();
@@ -0,0 +1,39 @@
import { HttpErrorResponse } from '@angular/common/http';
import { Result } from 'neverthrow';
import { z, ZodError } from 'zod';
import * as Sentry from '@sentry/capacitor';
import { ColoredLoggerService } from '../logger/colored/service';
export function SocketStreamReturn(schema: z.ZodTypeAny, context: string) {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = async function (...args: any[]) {
const result: Result<any, HttpErrorResponse> = await originalMethod.apply(this, args);
if(result.isOk()) {
try {
// Validate the result using the provided schema
schema.parse(result.value);
} catch (error) {
if (error instanceof ZodError) {
// If validation fails, throw an error with the details
//
ColoredLoggerService.error(error.errors, 'socket unexpected data structure '+ context, schema._def.description)
} else {
console.log('failed to setup the SocketStreamReturn successful')
// Throw any other unexpected errors
throw error;
}
}
} else {
}
return result;
}
return descriptor;
}
}
@@ -1,5 +1,7 @@
import { err } from 'neverthrow';
import { Schema } from 'zod';
import { Schema, ZodError } from 'zod';
import { ColoredLoggerService } from '../logger/colored/service';
import { TracingType } from '../monitoring/opentelemetry/tracer';
export function ValidateSchema(schema: Schema) {
return (
@@ -14,8 +16,54 @@ export function ValidateSchema(schema: Schema) {
args[0] = model;
return originalMethod.apply(this, args);
} catch (e) {
if (e instanceof ZodError) {
// If validation fails, throw an error with the details
//
ColoredLoggerService.error(e.errors, 'socket unexpected data structure '+ schema._def.description)
}
return err(e)
}
};
};
}
export function SafeValidateSchema(schema: Schema, context: string) {
return (
target: unknown,
propertyKey: string,
descriptor: PropertyDescriptor,
) => {
const originalMethod = descriptor.value;
descriptor.value = function (...args: unknown[]) {
const tracing: TracingType = args[args.length - 1] as any;
try {
const model = schema.parse(args[0]);
args[0] = model;
return originalMethod.apply(this, args);
} catch (e) {
if (e instanceof ZodError) {
// If validation fails, throw an error with the details
//
// If validation fails, throw an error with the details
console.error('unexpected data structure', context)
// Capture the Zod validation error with additional context
console.error('Validation failed:', e.errors);
tracing?.setAttribute?.('APIReturn.error', 'true')
let i = 0;
for(const schema of e.errors) {
tracing?.setAttribute?.('map.error.schema-'+i, JSON.stringify(schema))
}
ColoredLoggerService.error(e.errors, 'socket unexpected data structure '+ context, schema._def.description)
}
return originalMethod.apply(this, args);
}
};
};
}
@@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { CaptureLogService } from './capture-log.service';
describe('CaptureLogService', () => {
let service: CaptureLogService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(CaptureLogService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});
@@ -32,8 +32,3 @@ export const OpentelemetryAgendaProvider = createProvider('FO-agenda-service');
export const OpentelemetryNotificationProvider = createProvider('FO-notification');
export const OpentelemetryInterceptorProvider = createProvider('FO-interceptor');
export const OpentelemetryPublicationProvider = createProvider('FO-publication-service');
@@ -18,7 +18,6 @@ Device.getInfo().then(e => {
device = e
});
const createTracingInstance = ({bugPrint, name, module, autoFinish}): TracingType => {
const requestId = uuidv4()
@@ -59,6 +58,10 @@ const createTracingInstance = ({bugPrint, name, module, autoFinish}): TracingTyp
setAttribute: (key: string, value: string) => {
data.tags[key] = value;
span.setAttribute(key, value);
if(key =='outcome' && value == 'failed') {
span.setAttribute('error', 'true')
}
},
getAttribute: (key: string) => {
return data.tags[key]
@@ -16,7 +16,7 @@
</div>
</div>
<div class="d-flex header-bottom" >
<div class="header-bottom-icon">
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " src="assets/icon/icons-user.svg"></ion-icon>
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " src="assets/icon/theme/gov/icons-user.svg"></ion-icon>
@@ -42,8 +42,8 @@
<div class="messages height-100 width-100 d-flex flex-column" #scrollMe>
<div
*ngFor="let message of roomMessage$ | async" class="messages-list-item-wrapper"
<div
*ngFor="let message of roomMessage$ | async" class="messages-list-item-wrapper"
[ngClass]="{'my-message': message.sender.wxUserId === sessionStore.user.UserId, 'other-message': message.sender.wxUserId !== sessionStore.user.UserId}">
{{ message.message }} == {{ message.id }}
</div>