【问题标题】:In Angular (v6), socket.io 'on' method's (socket.on()) callback function is not getting called for 'message' type在 Angular (v6) 中,socket.io 'on' 方法的 (socket.on()) 回调函数不会为 'message' 类型调用
【发布时间】:2018-10-14 06:08:24
【问题描述】:

我正在开发一个演示 WebSocket 应用程序。技术栈包括以下内容:

前端:

  • Angular(v6)
  • Socket.io

网络服务器:

  • Nginx

后端:

  • 烧瓶
  • Flask-Socketio
  • uWSGI

我能够建立 WebSocket 连接,还能够从我的网络应用程序发送/接收消息。我可以在Chrome -> Network -> WS 部分看到正在发送/接收的消息,如下所示。

所以,我发送Hey!! 并接收回'message', 'my message'。这部分在我看来没问题。 问题是现在我想把这个incoming message 显示在我的应用程序中。但是,我 无法 存储此消息或 console.log() 来自服务器的传入响应,因为 socketio.on('message', callback()) 回调方法没有被触发,它本质上具有处理传入消息的逻辑,如图所示下面:

这是来自app.service.ts 的部分代码块,它工作。完整的代码sn-p贴在下面。

 public onMessage(): Observable<any> {
return new Observable<any>(observer => {
  console.log('hereeee');// This console happens
  // This below method is not firing
  this.socket.on('message', (data: any) => {
    console.log('Received a message from websocket service');
    observer.next(data);
  });
});

}

我在下面粘贴完整的服务器和客户端代码 sn-ps。

服务器:

@socketio.on('message', namespace='/websocket_test')
def msg(msg):
    socketio.emit('message', 'my message', room=request.sid)

客户:

我正在使用 Angular + RxJS 来定义我的 socket.io 服务方法。另外,我在下面的 sn-ps 中添加了comments 以指示哪些有效,哪些无效。

app.service.ts

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

export enum Event {
  CONNECT = 'connect',
  DISCONNECT = 'disconnect'
}
     @Injectable()
        export class AppService {
      constructor(private http: HttpClient) {
      }

      private socket;

      public initSocket(): void {
        this.socket = socketIo('/websocket_test');
      }

      // This method is used to send message to backend
      public sendMe(message: any): void {
        this.socket.emit('message', {data: message});
      }

      public onMessage(): Observable<any> {
        return new Observable<any>(observer => {
          console.log('hereeee'); // This console happens
          // This below method is not firing
          this.socket.on('message', (data: any) => {
            console.log('Received a message from websocket service');
            observer.next(data);
          });
        });
      }

      // This gets called on connect and disconnect event.
      public onEvent(event: Event): Observable<any> {
        return new Observable<Event>(observer => {
          this.socket.on(event, () => observer.next());
        });
      }

    }

app.component.ts

import {Component, OnInit} from '@angular/core';
import {AppService} from './app.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})


export class AppComponent implements OnInit {
  messages = [];
  isConnected: boolean;

  constructor(private appService: AppService) {
  }

  ngOnInit() {
    this.initIoConnection();
  }

  private initIoConnection(): void {
    this.appService.initSocket();

    // This happens
    this.appService.onEvent(Event.CONNECT)
      .subscribe(() => {
        this.isConnected = true;
        console.log('connected');
      });

    this.appService.onMessage()
      .subscribe((message: any) => {
        // not getting called
        console.log('Message', message);
        this.messages.push(message);
        // console.log(this.messages);
      });

    this.appService.onEvent(Event.DISCONNECT)
      .subscribe(() => {
        this.isConnected = false;
        console.log('disconnected');
      });
  }

  public myMessage(message: string): void {
    if (!message) {
      return;
    }

    this.appService.sendMe({
      from: this.user,
      content: message
    });
    this.messageContent = null;
  }
}

export enum Event {
  CONNECT = 'connect',
  DISCONNECT = 'disconnect'
}

我尝试了几件事来解决这个问题,但没有运气。如果有人熟悉此问题或对我做错了什么有任何想法,请在此处发表评论。任何输入将不胜感激。让我知道是否需要任何其他详细信息。谢谢!

【问题讨论】:

    标签: angular flask websocket socket.io flask-socketio


    【解决方案1】:

    在检查了自己并在网上浏览了几个示例后,我发现了我的应用程序的问题。它在后端。

    如果您注意到我在上述问题中分享的server 侧sn-p,我将像这样定义socketio 事件:

    from server.main import socketio
    
    @socketio.on('message', namespace='/websocket_test')
    def msg(msg):
        socketio.emit('message', 'my message', room=request.sid)
    

    所以,我正在从main/__init__.py 文件中执行importsocketio,在该文件中我声明了我的flask 应用程序并初始化了socketio 实例。我正在使用该实例以socketio.emit('message', 'my message', room=request.sid) 向客户端发出事件。这在这里(我发出的方式是问题)。正确的方法是在这个文件中导入emit 并使用它,如下所示:

    from server.main import socketio
    from flask_socketio import emit
    
    @socketio.on('message', namespace='/websocket_test')
    def msg(msg):
        emit('message', 'my message', room=request.sid)
    

    如果有人在这里有任何意见,请告诉我。我希望它会帮助那些遇到类似问题的人:)

    【讨论】:

    • emit() 函数是上下文感知的。它将在传入事件的同一命名空间上发出 (/websocket_test)。 socket.emit() 函数是一个不使用上下文信息的通用函数,如果您不提供命名空间,那么它将在默认命名空间而不是您正在使用的命名空间上发出。
    • @Miguel - 感谢您解释差异。现在,我明白为什么我的 /websocket_test 命名空间失败了。
    猜你喜欢
    • 2018-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-02
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多