3

Clientside I used Angular 6 and Serverside i used node.js.

Here in angular 6 console it print message and socket.io id({message: "Hello World", id: "6An-ctwlwbZZWrfMAAAB"}) after using below code.

this code is right or any change in this code bcoz I am not sure about this code kindly help to make correct this.

and another query is I have more than 15 components in my project so how to make common use this socket.io for all components or I have to import this app.component.ts code in all another component.

app.js(serverside)

after installing (npm i socket.io)

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

server.listen(3000,function(req,res){
  console.log("listen at 3000!");
});

io.on('connection',(socket) => {
  socket.emit('hello',{
    message : 'Hello World',id: socket.id
  })
});

app.component.ts(clientside)

after installing (npm i socket.io)

import * as socketIo from 'socket.io-client';

export class AppComponent implements OnInit {
  ngOnInit(){
    const socket = socketIo('http://localhost:3000/');
      socket.on('hello',(data) => console.log(data));
    }
  }
}
6
  • 1
    check this:blog.codewithdan.com/… Commented Sep 29, 2018 at 10:16
  • are you getting any error? Commented Sep 29, 2018 at 10:23
  • no i not getting any error console prints in crome browser like this ({message: "Hello World", id: "6An-ctwlwbZZWrfMAAAB"}) but i have more than 15 components so i dont know how to use socket.io common for all component and u told me make service for that but with service how to fetch socket.io angular to node for all components Commented Sep 29, 2018 at 10:25
  • can you try my example code Commented Sep 29, 2018 at 10:38
  • i am trying, i dont know what is this in serive import { Socket } from '../shared/interfaces'; Commented Sep 29, 2018 at 10:45

3 Answers 3

7

The one way to achieve this mechanism is using ngx-socket-io, connect your node server at the module level or root level i have implemented like below

app.module.ts code

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { SocketIoModule, SocketIoConfig } from 'ngx-socket-io';
import { AppComponent } from './app.component';
const config: SocketIoConfig = { url: 'http://192.168.1.187:9301', options: {}  };
@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    SocketIoModule.forRoot(config),
    FormsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

create one service which handles your incoming and outgoing traffic.

import { Injectable } from '@angular/core';
import { Socket } from 'ngx-socket-io';
@Injectable({
  providedIn: 'root'
})
export class SocketService {

  constructor(public socket: Socket) { }
  getMessage() {
    return this.socket
        .fromEvent<any>('msg')
        .map(data => data.msg);
}

sendMessage(msg: string) {
    this.socket.emit('msg', msg);
}
}

Update your code in your component file

export class AppComponent implements OnInit {
  constructor(private socketService: SocketService) {}
  title = 'app';
  incomingmsg = [];
  msg = 'First Protocol';
  ngOnInit() {
    this.socketService
        .getMessage()
        .subscribe(msg => {
          console.log('Incoming msg', msg);
        });
        this.sendMsg(this.msg);
  }
  sendMsg(msg) {
    console.log('sdsd', msg);
    this.socketService.sendMessage(msg);
 }
}
Sign up to request clarification or add additional context in comments.

5 Comments

getMessage() { return this.socket .fromEvent<any>('msg') .map(data => data.msg); } this is giving me error in .map
What version of angular you are using?
i am using angular 7
how to add bearer token in this example? the config is in appmodule,but bearer can be available later in some other module,how to add that to each request.
3

Create Service and turn your socket data into Observable stream

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

@Injectable()
export class ChatService {

  observable: Observable<string>;
  socket;

  constructor() {
    this.socket = io('http://localhost:3000');     
   }

   getData(): Observable<string> {
    return this.observable = new Observable((observer) => 
      this.socket.on('hello', (data) => observer.next(data))
    );
  }

  // This one is for send data from angular to node 
  pushData(e) {
    this.socket.emit('hello', e);
  }
}

Then Call from component

App.component.ts

import { Component } from '@angular/core';
import { ChatService } from './common/chat.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {  
  title;
  chat;
  constructor(private cService: ChatService) {
    this.cService.getData().subscribe(data => console.log(data));
  }

  onClick(e: string) {
    this.cService.pushData(e);
    this.chat = '';
  }
}

Comments

2

You can create a service for working with a socket. E.g (of course this is a very simple example):

/* e.g app/shared/io/io.service.ts */

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';

import * as socketIo from 'socket.io-client';

const SERVER_URL = '/';

/** Your events enum */
export enum IOEventName {
    EVENT_NAME_1 = "EVENT_NAME_1",
    EVENT_NAME_2 = "EVENT_NAME_2",
    ...
}

/** Interfaces for your event messages */
export interface IEventName1Message {
    propOne: number,
    propTwo: string,
    ...
}

export interface IEventName2Message {
    propOne: Date,
    propTwo: Boolean,
    ...
}
...

@Injectable()
export class SocketService {
    private socket: SocketIOClient.Socket;

    public initSocket(): void {
        this.socket = socketIo(SERVER_URL);
    }

    public onEvent<T>(event: IOEventName): Observable<T | Array<T>> {
        return new Observable<T>(observer => {
            this.socket.on(event, (data: T) => observer.next(data));
        });
    }

    public destroy() {
        if (this.socket) {
            this.socket.removeAllListeners();
            this.socket.close();
            this.socket = undefined;
        }
    }
}

And use it in any components:

import { SocketService, IOEventName, IEventName1Message, IEventName2Message } 
    from 'app/shared/io/io.service';

export class AppComponent implements OnInit, OnDestroy {
    constructor(private socketService: SocketService) { }

    ngOnInit() {
        this.socketService.initSocket();
        this.socketService
            .onEvent<IEventName1Message>(IOEventName.EVENT_NAME_1)
            .subscribe(data => { /* message received */ });

        this.socketService
            .onEvent<IEventName2Message>(IOEventName.EVENT_NAME_2)
            .subscribe(data => { /* message received */ });
    }

    ngOnDestroy() {
        this.socketService.destroy();
    }
}

4 Comments

import { SocketService, IOEventName, IEventName1Message, IEventName2Message } from 'app/shared/io/io.service'; how to import this? and my node.js code is right ?
@AmishaRana app/shared/io/io.service is first code block of my example. It is angular code.
This example is good but could be improve. Why are you returning each time a new Observable in the "onEvent" function ? Since this function can be used by many component. You should only create one by IOEventName. The initSocket is not that nice, the initSocket should be the service contructor. You should not open two socket for the same url.
@xrobert35 You're right. This is a simple example, it could be improve.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.