typescript - Hur tar jag emot meddelanden från en websocket-server och fyller en Angular-komponent


Jag lär mig hur man integrerar livechatt i ett Angular-projekt med Socket.IO och följer den här handledningen jag hittade

Jag lade till en inmatningsruta i min komponent och skickar nu framgångsrikt ett meddelande från komponenten till servern.

Problemet som jag stöter på är att jag inte vet hur man använder emit för att skicka meddelandet tillbaka till användaren och uppdatera DOM.

Jag kommer att gå igenom min kod. Chattfönstret har inte sin egen komponent men så småningom kommer det att ha det. Här är TypeScript-koden för där chattfönstret finns. Jag skapar ett kortspel så du kommer att märka referenser till kortlekar och givare.

import { Component, OnInit, OnDestroy } from '@angular/core';
import { DealerService } from '../services/dealer.service';
import { ChatService } from '../services/chat.service';


@Component({
  selector: 'app-blackjackgame',
  templateUrl: './blackjackgame.component.html',
  styleUrls: ['./blackjackgame.component.css']
})
export class BlackjackgameComponent implements OnInit, OnDestroy {

  constructor(private dealer: DealerService, private chat: ChatService) { }

  ngOnInit() {
    this.dealer.generateDeck();
    this.dealer.shuffle(5);
    this.chat.messages.subscribe(msg => {
      console.log(msg);
    });

  }

  // This is now working
  sendMessage(message: string) {
    this.chat.sendMsg(message);
  }


  // Is this proper way to do this? I'm not sure
  updateMessages(message: string) {
    console.log('message was emitted: ' + message);
  }

  ngOnDestroy() {
    // no longer needed since generateDeck has it's own destroy
    // this.deckService.destroy_deck();
  }

}

Jag har två huvudsakliga tjänster, chattjänst och WebSocket-tjänst.

Chatttjänsten ser ut så här

import { Injectable } from '@angular/core';
import { WebsocketService } from './websocket.service';
import { Observable, Subject } from 'rxjs/Rx';

@Injectable()
export class ChatService {

  messages: Subject<any>;

  constructor(private wsService: WebsocketService) {
    this.messages = <Subject<any>>wsService
      .connect()
      .map((response: any): any => {
      return response;
    });
  }

  sendMsg(msg){
    this.messages.next(msg);
  }

}

Och min WebSocket-tjänst ser ut så här

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


@Injectable()
export class WebsocketService {

  private socket; // socket that connects to our socket.io server
  constructor() { }

  connect(): Rx.Subject<MessageEvent> {
    this.socket = io(environment.ws_url);

    const observable = new Observable(observer => {
      this.socket.on('message', (data) => {
        console.log('Received a message from websocket service');
        observer.next(data);
      });
      return () => {
        this.socket.disconnect();
      };
    });

    const observer = {
      next: (data: Object) => {
        this.socket.emit('message', JSON.stringify(data));
      }
    };

    return Rx.Subject.create(observer, observable);
  }

}

Och slutligen har jag en websocket-server skriven i vanlig javascript. Du har sett en del av den i mitt foto ovan. Den fullständiga koden ser ut så här

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);



/*io.on('connection', function(socket){
    console.log('Connection made');
    socket.on('chat message', function(msg){
        io.emit('chat message', msg);
    });
});*/

io.on('connection', function(socket){
    console.log('connection');
    socket.on('message', function(message){
        console.log('Message received: ' + message);
        io.emit('message', {type:'new-message', text:message});
    })
})

http.listen(5000, function(){
  console.log('listening on *:5000');
});

Så igen, jag har min websocket-server som loggar när den tar emot ett meddelande. Min fråga är, hur gör jag för att gå åt andra hållet? Jag vill uppdatera min DOM i komponenten med det nya meddelandet baserat på det utsända meddelandet från WebSocket. Alla förslag tas tacksamt emot; jag är väldigt ny på detta.

Svar #1

Så jag klurade ut svaret. Jag var ganska nära. Jag skapade en ny chattkomponent. Här är koden för det.

Chatbox-komponent HTML

<div id="chatDisplay">
  <ul>
    <li *ngFor = "let msg of messages">{{msg}}</li>
  </ul>
</div>
<div id="chatInput">
  <input type="text" id="chatBox" #chatMessage>
  <button (click)="sendMessage(chatMessage.value)">Send Message</button>
</div>

Chatbox-komponent TypeScript

import { Component, OnInit, OnDestroy } from '@angular/core';
import { ChatService } from '../services/chat.service';
import { Observable, Subject } from 'rxjs/Rx';

@Component({
  selector: 'app-chatbox',
  templateUrl: './chatbox.component.html',
  styleUrls: ['./chatbox.component.css']
})
export class ChatboxComponent implements OnInit, OnDestroy {

  messages = [];
  constructor(private chat: ChatService) { }

  ngOnInit() {
    this.chat.messages.subscribe(msg => {
      this.messages.push(msg.text);
    });
  }

  sendMessage(message: string){
    this.chat.sendMsg(message);
  }

  ngOnDestroy() {
  }

}