Not able to call Service inside WebSocket listener in Nestjs

霸气de小男生 提交于 2020-02-06 16:21:28

问题


I have implemented WebSockets in Nestjs using below method and one of the requirement is that I need to update the db once I receive any message from websocket server. In order to do that I have done the below code but getting error like this:

But if I call the same method inside any other controller method it works fine(check /test1). Only when I call it from websocket listener I'm getting this error. Even if I call simple method from same controller to just print some log, I'm getting the same error TypeError: this.processData is not a function. Weird!

Can someone tell me what am I doing wrong with this?

(node:11421) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'updateResponseData' of undefined
    at WebSocket.incoming (/opt/dist/controller/sample.controller.js:62:44)
    at WebSocket.emit (events.js:210:5)
    at Receiver.receiverOnMessage (/opt/node_modules/ws/lib/websocket.js:800:20)
    at Receiver.emit (events.js:210:5)
    at Receiver.dataMessage (/opt/node_modules/ws/lib/receiver.js:423:14)
    at Receiver.getData (/opt/node_modules/ws/lib/receiver.js:353:17)
    at Receiver.startLoop (/opt/node_modules/ws/lib/receiver.js:139:22)
    at Receiver._write (/opt/node_modules/ws/lib/receiver.js:74:10)
    at doWrite (_stream_writable.js:431:12)
    at writeOrBuffer (_stream_writable.js:415:5)
    at Receiver.Writable.write (_stream_writable.js:305:11)
    at Socket.socketOnData (/opt/node_modules/ws/lib/websocket.js:875:35)
    at Socket.emit (events.js:210:5)    
    at addChunk (_stream_readable.js:308:12)
    at readableAddChunk (_stream_readable.js:289:11)
    at Socket.Readable.push (_stream_readable.js:223:10)
(node:11421) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:11421) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Controller Code :

import { Controller, Post, Get, Inject, Req, UsePipes, Body, Header,Param } from '@nestjs/common';
import { Request } from 'express';
import * as WebSocket  from 'ws';
import { DatabaseService } from '../service/datafetch.service';

@Controller('sample')
export class SampleController {

    @Inject(dbService)
    private dbService: DatabaseService;

    static ws: any;
    static wsnew: any;
    public receiveDistData = '';

    // Connect WS & Listen to messages
    constructor() {
        this.initWs();     

        SampleController.ws.on('message', async function incoming(data) {
            console.log('message recieved 8081');
            var dataJson = JSON.parse(data);
            await this.dbService.updateResponseData(dataJson);
            return data;       
        }); 
    }

    @Get('/test/data/:id')
    async testData(@Param('id') id: string) {
        return await this.callWs(id);
    }

    @Get('/test1/data/:id')
    async testData1(@Param('id') id: string) {
        const data = {id: id, data:{}};
        return await this.dbService.updateResponseData(data);
    }

    async initWs() {
        SampleController.ws = new WebSocket('ws://127.0.0.1:8081');
    }

    async processData() {
        console.log('Printing a log...');
    }

    // Data Distribution
    async callWs(id) {    
        // If Socket is not opened, try to re-open    
        if(SampleController.ws.readyState != 1) { 
            console.log('Server is dead....');
            this.initWs();
        }

        const Data = await this.dbService.findAll(id);
        await SampleController.ws.send(JSON.stringify({
            event: 'channel1',
            data: Data,
        }));
    }

}

Repository Code:

import { InjectRepository } from '@nestjs/typeorm';
import { Injectable } from '@nestjs/common';
import { Repository } from 'typeorm';
import { SampleRepository } from '../repository/sample.repository';

@Injectable()
export class SampleService {

  constructor(
    @InjectRepository(SampleRepository)
    private readonly sampleRepository: SampleRepository
  ) {}

  async updateResponseData(data): Promise<any> {
    return await this.sampleRepository.updateData(data);
  }

}

回答1:


Inside an anonymous function, this refers to the global object, not the instance of your service.

Instead you can use an arrow function. Here, this refers to the class instance, as you would expect:

async function(data) {
  // this is global object
  this.call();


(data) => {
  // this is the same as in enclosing object
  this.call();


来源:https://stackoverflow.com/questions/59611737/not-able-to-call-service-inside-websocket-listener-in-nestjs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!