socket.emit работает только после завершения рекурсивной функции (реализованной с использованием requestAnimationFrame) - PullRequest
0 голосов
/ 16 июня 2020

Я пытаюсь бесконечно отправлять массив на свой сервер со стороны клиента, используя рекурсивную функцию, и соответственно получать ответ от моего сервера, однако сообщения с моего сервера не возвращаются в реальном времени, это только после рекурсивной функции завершается отправка сообщений с сервера.

Я не уверен, проблема в коде на стороне клиента или на стороне сервера. Заранее спасибо.

Это мой сервер. js скрипт.

var express = require('express');
var app = express();

var https = require('https').createServer(sslOptions, app);
var io = require('socket.io')(https);

const port = 8080;
const host = "x.x.x.x"; // my host server IP address

io.on('connection', (socket) => {
  console.log('a user connected');
  socket.on('predict', (data)=>{
  
      // this line is executed after recursive function at client side is stopped
      console.log("socket from client");
      
      // this line is executed after after recursive function at client side is stopped
      socket.emit('result', { "message": "hello world from server"});
  });
});


https.listen(port, host);

Это мой скрипт app.component.ts.

// this is my recursive function
    detectFromVideoFrame = (model, video, stop_detecting) => {
     
    this.detect(video).then(predictions => { 

      // stop recursive loop if stop_detecting == true
      if(!(this.stop_detecting)){

        requestAnimationFrame(() => {
          this.detectFromVideoFrame(model, video, stop_detecting);
        });
      }
    }, (error) => {
      console.error(error)
    });
  };

this.dataService.setupSocketConnection();

// these two lines are in this.detect function
this.dataService.getTFprediction(imageTensorArr);
      
this.dataService.onNewMessage().subscribe(msg => {
  console.log('got a msg: ', msg);
});

Это мой скрипт service.ts

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import * as io from 'socket.io-client';

@Injectable({
  providedIn: 'root'
})
export class DataService {
  private socket: SocketIOClient.Socket;

  constructor() {}
  setupSocketConnection() {
    this.socket = io('https://x.x.x.x:8080');
    this.socket.on('connect', function () {
      console.log("socket connected on client side");
    });
  }

  getTFprediction(videoArray){
  
    // this line is executed normally each time this function is called at the app.component.ts script
    console.log("check connection: ", this.socket.connected);
    
    // I'm not sure when is this line executed
    this.socket.emit('predict', { "data": videoArray } )
  }

  onNewMessage() {
    return Observable.create(observer => {
      this.socket.on('result', msg => {
        console.log(msg.message);
        observer.next(msg);
      });
    });
  }

}

1 Ответ

0 голосов
/ 24 июля 2020

Похоже, это проблема:

  onNewMessage() {
    return Observable.create(observer => {
      this.socket.on('result', msg => {
        console.log(msg.message);
        observer.next(msg);
      });
    });
  }

Обработчик событий сокета - это то, что вы хотели бы инициализировать при создании клиента socketio, а не при подписке на наблюдаемый объект.

Я бы рекомендовал сделать это, как показано ниже:

  resultSubject = new Subject();

  setupSocketConnection() {
    this.socket = io('https://x.x.x.x:8080');
    this.socket.on('connect', function () {
      console.log("socket connected on client side");
    });

    this.socket.on('result', (event) => {
      this.resultSubject.next(event);
    });
  }

В app.component

class AppComponent {
  constructor(private dataService: DataService) {}

  this.dataService.resultSubject
      .subscribe((message) => {
        console.log('received from socket: ', message);
      });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...