如何使用 angular 和 socket io 显示来自 feathersjs 服务器的实时数据

How to display real time data from the feathersjs server using angular and socket io

我已经实现了一个羽毛服务来从温度传感器获取数据,我想使用 angular 和套接字 io 显示实时数据。目前我在服务器控制台收到 'user connected' 消息,但我无法弄清楚如何在 angular 客户端显示数据。

这是我的服务器端代码 (app.js)

const path = require('path');
const favicon = require('serve-favicon');
const compress = require('compression');
const helmet = require('helmet');
const cors = require('cors');
const logger = require('./logger');
const io = require('socket.io-client');
const feathers = require('@feathersjs/feathers');
const configuration = require('@feathersjs/configuration');
const express = require('@feathersjs/express');
const socketio = require('@feathersjs/socketio');
const middleware = require('./middleware');
const services = require('./services');
const appHooks = require('./app.hooks');
const channels = require('./channels');
const mongodb = require('./mongodb');


// Set up Socket.io client with the socket

const app = express(feathers());

app.configure(socketio());

app.configure(socketio(function(io) {
    io.on('connection', (socket) => {

        socket.emit('message', { text: 'A client connected!' });
        console.log('user connected');


            socket.send('Sent a message 4seconds after connection!');
            console.log('message sent');

            socket.on('clientEvent', function(data) {
                console.log(data);});

    });   
    io.use(function (socket, next) {
        // Exposing a request property to services and hooks
        socket.feathers.referrer = socket.request.referrer;
        next();
      });

}));

messages.class.js

const { Service } = require('feathers-mongodb');
const MongoClient = require('mongodb').MongoClient;

exports.Messages = class Messages extends Service {
  constructor(options, app) {
    var cors = require('cors')

    var awsIot = require('aws-iot-device-sdk');

//
// Replace the values of '<YourUniqueClientIdentifier>' and '<YourCustomEndpoint>'
// with a unique client identifier and custom host endpoint provided in AWS IoT.
// NOTE: client identifiers must be unique within your AWS account; if a client attempts 
// to connect with a client identifier which is already in use, the existing 
// connection will be terminated.
//
var device = awsIot.device({
   keyPath: '*****************',
  certPath: '*****************',
    caPath: '*****************',
  clientId: '*****************',
      host: '*****************'
});


device
  .on('connect', function() {
    console.log('connect');
    device.subscribe('outTopic');
    //device.publish('appoutTopic', JSON.stringify({ test_data: 1}));
  });

device
  .on('message', function(topic, payload) {

    var obj = JSON.parse(payload);
    var msg = JSON.stringify(obj);


    MongoClient.connect('mongodb://localhost:27017/feathers')
    .then(function(client){
      // Set the model now that we are connected
      app.service('messages').Model = client.db('feathers').collection('messages');

      app.service('messages').create({
        msg
      }).then(message => console.log('Created message', message));
    }).catch(error => console.error(error));

    const messages = app.service('messages');

    messages.on ('created', (message,context)=> console.log('created',message,context));


  });

    super(options);



  }
};

angular 服务 (chat.service.ts)

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



@Injectable({
  providedIn: 'root'
})
export class ChatService {
  private url: string = 'http://localhost:8080';
  public socket: SocketIOClient.Socket;
  public app: any;   

  constructor() {
    this.socket = io(this.url);

    this.app = feathers()
      .configure(socketio(this.socket))
      .configure(hooks());
   }


   getMessages() {
    let observable = new Observable(observer => {
      this.socket.on('created', (message) => {
        console.log(message);
        observer.next(message);    
      });
      return () => {
        this.socket.disconnect();
      };  
    })     
    return observable;
  }  
}

receive.components.ts

import { Component, OnInit, OnDestroy } from '@angular/core';
import { FormControl }           from '@angular/forms';
import { ChatService }       from '../chat.service';

@Component({

  selector: 'app-receive',
  templateUrl: './receive.component.html',
  styleUrls: ['./receive.component.css'],
  providers: [ChatService]
})
export class ReceiveComponent implements OnInit, OnDestroy {
  messages = [];
  connection;
  message;

  constructor(private chatService:ChatService) {}


  ngOnInit() {
    this.connection = this.chatService.getMessages().subscribe(message => {
      this.messages.push(message);
    })
  }

  ngOnDestroy() {
    this.connection.unsubscribe();
  }
}

由于这是我在 Whosebug 中的第一个问题,请原谅我的错误并指出它们,以便我可以相应地更新问题。

Feathers guide, specifically the quick start and the frontend guide 解释了一切是如何组合在一起的。

还有 feathers-reactive which gives you real-time observables automatically and the feathers-chat-angular 和 Angular (8) 使用 feathers-reactive 的聊天应用程序示例。

在您的情况下,您不想在 getMessages 中的套接字 (this.socket) 上监听,而是在 this.app 中的 messages 服务上监听:

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



@Injectable({
  providedIn: 'root'
})
export class ChatService {
  private url: string = 'http://localhost:8080';
  public socket: SocketIOClient.Socket;
  public app: any;   

  constructor() {
    this.socket = io(this.url);

    this.app = feathers()
      .configure(socketio(this.socket))
      .configure(hooks());
   }


   getMessages() {
    let observable = new Observable(observer => {
      this.app.service('messages').on('created', (message) => {
        console.log(message);
        observer.next(message);    
      });
      return () => {
        this.socket.disconnect();
      };  
    })     
    return observable;
  }  
}