multiple sockets on one client using angular

25
May 15, 2019, at 11:40 PM

I'm not even sure if this is possible. If not, please point me in a different direction.

I have a server that allows for multiple socket-io connections. The server generates a random number and emits to registered sockets.

On the client side, I want to initialize two sockets and display the same data generated from the server. These two sockets are displayed on one template.

Server
const express = require('express'),
      app = express(),
      server = require('http').createServer(app);
      io = require('socket.io')(server);
let timerId = null,
    sockets = new Set();
//This example emits to individual sockets (track by sockets Set above).
//Could also add sockets to a "room" as well using socket.join('roomId')
//https://socket.io/docs/server-api/#socket-join-room-callback
app.use(express.static(__dirname + '/dist')); 
/*
everytime there is a new connection, there is a new socket
*/
io.on('connection', socket => {
  sockets.add(socket);
  console.log(`Socket ${socket.id} added`);
  if (!timerId) {
    startTimer();
  }
  socket.on('clientdata', data => {
    console.log(data);
  });
  socket.on('disconnect', () => {
    console.log(`Deleting socket: ${socket.id}`);
    sockets.delete(socket);
    console.log(`Remaining sockets: ${sockets.size}`);
  });
});
/**
 * for each socket, we emit the same value
 */
function startTimer() {
  //Simulate stock data received by the server that needs 
  //to be pushed to clients
  timerId = setInterval(() => {
    if (!sockets.size) {
      clearInterval(timerId);
      timerId = null;
      console.log(`Timer stopped`);
    }
    let value = ((Math.random() * 50) + 1).toFixed(2);
    //See comment above about using a "room" to emit to an entire
    //group of sockets if appropriate for your scenario
    //This example tracks each socket and emits to each one
    for (const s of sockets) {
      console.log(`Emitting value: ${value}`);
      s.emit('data', { data: value });
    }
  }, 2000);
}
server.listen(8080);
console.log('Visit http://localhost:8080 in your browser');
Client

app.component.ts

Here is where I am trying to solve this problem. I have two different stockQuote variables and two different subscriptions for the two different sockets.

import { Component, OnInit, OnDestroy } from '@angular/core';
import { DataService } from './core/data.service';
import { Subscription } from 'rxjs';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'health-status-dashboard';
  stockQuote: number;
  stockQuote1: number;
  sub: Subscription;
  sub1: Subscription;
  constructor(private dataService: DataService) { }
  ngOnInit() {
    this.sub = this.dataService.getQuotes()
      .subscribe(quote => {
        this.stockQuote = quote;
      });
    this.sub1 = this.dataService.getQuotes()
      .subscribe(quote => {
        this.stockQuote1 = quote;
      });
  }
  ngOnDestroy() {
    this.sub.unsubscribe();
  }
}

app.component.html

<h2>Quote: {{ stockQuote }}</h2>
<h2>Quote1: {{ stockQuote1 }}</h2>
Service

Here, I am trying to create a new socket each time getQuotes() is called. (It is called twice in app.component.ts's ngOnInit() method. So two sockets are created.

import { Injectable } from '@angular/core';
//TODO: why cannot import?
import { Observable } from 'rxjs';
import { Observer } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
import * as socketIo from 'socket.io-client';
import { Socket } from '../shared/interfaces';
declare var io: {
  connect(url: string): Socket;
}
/**
 * TODO: need to test
 */
function isError(error: Error): error is Error {
  return (<Error>error) !== undefined;
}
@Injectable()
export class DataService {
  sockets: Socket[] = [];
  observer: Observer<number>;
  /**
   * previously: there was one socket variable and a new socket was created each time still but just overwrote
   the previous socket. still, the previous socket exists.
   */
  getQuotes(): Observable<number> {
    const soc: Socket = socketIo('http://localhost:8080');
    //this.sockets.push(soc);
    soc.on('data', (res) => {
      this.observer.next(res.data);
    });
    return this.createObservable();
  }
  createObservable(): Observable<number> {
    return new Observable(observer => {
      this.observer = observer;
    });
  }
  private handleError(error) {
    console.error('server error:', error);
    if (isError(error.error)) {
      let errMessage = error.error.message;
      return Observable.throw(errMessage);
    }
    return Observable.throw(error || 'Socket.io server error');
  }
}

interfaces.ts

export interface Socket {
  on(event: string, callback: (data: any) => void);
  emit(event: string, data: any);
}

On my app, only stockQuote1 is displayed (Quote1 in template) and stockQuote is blank (Quote in template).

I'm expecting both Quote and Quote1 to display the same value in the template.

In my logs it says that two sockets are added:

...
Socket s_-VWv34H6Vd7nN1AAAA added
Socket lENrl8vr_YvplUygAAAB added
...
Answer 1
@Injectable()
export class DataService {
  /**
   * previously: there was one socket variable and a new socket was created each time still but just overwrote
   the previous socket. still, the previous socket exists.
   */
  getQuotes(): Observable<number> {
    const soc = socketIo('http://localhost:8080');
    //this.sockets.push(soc);
    //create new Observable in function, and use `observer`
    return new Observable(observer => {
      soc.on('data', (res) => {
        observer.next(res.data);
      });
    });
  }
}

Why:
socket is can be connect multiple.
But, observer is one, so only last socket's value will arrive.
My code is using local observer in getQuotes() method.

For class variable, we need array of Observable<number>

READ ALSO
Meaning in nodejs/postgreSQL : query.query2+=&#39;DELETE FROM public.category_qb_map WHERE qb_id=${id};&#39;;

Meaning in nodejs/postgreSQL : query.query2+='DELETE FROM public.category_qb_map WHERE qb_id=${id};';

I am writing an api in nodejs, in which some data are taken from the body of the request and insert, update and delete operations are performedI am having difficulty in understanding some portions of the code

28
Get a variable from a file to another file in node.js( problem not solve )

Get a variable from a file to another file in node.js( problem not solve )

I tried too many time but I couldn't a get solution to my problemmy file structure is like following:

12
Why is my express code not rendering css and javascipt files?

Why is my express code not rendering css and javascipt files?

I am trying to write a basic express server codeHowever, the HTML file that gets served on a particular route does not render the static files (css, js and image files)

30