Socket IO Rooms Workflow Issue


#1

Hello,

I’m struggling to find the best to integrate socket.io into my Ionic application.

If I initialize socket io on my rooms page, all good i received my rooms and all. Then I click on my room and do a push to the room page where I cannot access my Socket.io instance.

So when I do a emit “join room” event, I get a “this.socketService.socket.emit is undefined.” .

If I reinitialize the socketservice on the room page, all is fine but I have two socket connections.

Can I not have just one instance? How would I do that?

chats.ts


import {SocketService} from '../shared/services/socket.service';

@Component({
    selector: 'page-chats',
    templateUrl: 'chats.html',
    providers: [SocketService]
})
export class ChatsComponent {

    allmyrooms;
    zone: NgZone;
    
    constructor(
        private navCtrl: NavController,
        private loadingCtrl: LoadingController,
        private alertCtrl: AlertController,
        public  socketService: SocketService,
        public  storage: Storage,
        private events: Events) {
            
            // GET USER
            this.storage.get('USER').then((user) => {

                this.socketService.initialize(user);

                this.zone = new NgZone({enableLongStackTrace: false});
                this.socketService.socketService.subscribe(event => {
                    console.log('message received from server... ', event);
                    if (event.category === 'logged in'){
                        this.zone.run(() => {
                            this.socketService.socket.emit('load rooms', this.socketService.user.id);
                        });
                    }
                    if (event.category === 'receiveRooms'){
                        this.zone.run(() => {
                            this.allmyrooms = event.rooms.rooms;
                        });
                    }
                    if (event.category === 'addedRooms'){
                        console.log(event);
                        this.zone.run(() => {
                            this.allmyrooms.push(event.room.room)
                        });
                    }
                });        
            }) 
            

    }

    openchat(room) {
        console.log(room);
        this.navCtrl.push(RoomComponent, {
            room: room
        });
    }

}

room.ts

import {Component, ViewChild, NgZone} from '@angular/core';
import {NavController, NavParams, LoadingController, Content} from 'ionic-angular';
import { Storage } from '@ionic/storage';

import * as io from 'socket.io-client';
import {SocketService} from '../shared/services/socket.service';

@Component({
    selector: 'page-room',
    templateUrl: 'room.html',
    providers: [RoomService, File, FileOpener, Camera, SocketService]
})
export class RoomComponent {
    
    @ViewChild(Content) content: Content;
    
    room = {
        id:1,
        name:'Room Name'
    };
    message:string;
    messages: Array<any> = [];
    zone:any;
    user:any;
    
    constructor(
        private navCtrl: NavController,
        private storage: Storage,
        private loadingCtrl: LoadingController,
        public socketService: SocketService,
        public navParams: NavParams) {

            this.messages = []; 

            this.zone = new NgZone({enableLongStackTrace: false});
            this.socketService.socketService.subscribe(event => {   
                console.log('message received from server... ', event);
                if (event.category === 'logged in'){
                    this.zone.run(() => {
                        this.socketService.socket.emit('join room', this.room.id); 
                    });
                }
                if (event.category === 'history'){
                    console.log(event);
                    this.zone.run(() => {
                        this.messages.push(event.history);
                    });
                }
                if (event.category === 'newMessage'){
                    this.zone.run(() => {
                        this.messages.push(event.message);
                        this.scrollToBottomNow(); 
                    });
                }
            });
            
    }
    
    ionViewWillEnter() {        
        this.room = this.navParams.get("room");
        this.socketService.joinRoom(this.room.id);
    }

    
    scrollToBottomNow() {
        this.content.scrollToBottom();   
    }
    
    send(message:string){
        this.message = "";
        this.storage.get('USER').then((user) => {
            let msgData = {
                user_type: 'ajk', 
                from_userid: user.id,
                from_username: user.nom +' '+user.prenom ,
                for_userid: 0, 
                for_username: '*', 
                avatar: user.avatar,
                message: message,
                room_id: this.room.id
            };
            this.socketService.sendMessage(msgData);
        });
    }
    
}

socketService.ts

import {Injectable} from '@angular/core';
import {Http} from '@angular/http';
import { Storage } from '@ionic/storage';
import {Config} from '../../../../app/app.config';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import * as io from 'socket.io-client';

@Injectable()
export class SocketService {

    socketObserver: any;
    socketService: any;
    public socket: any;
    user: any;
    data: any = null;
    socketHost: string = 'http://192.168.15.48:3008';
 
    constructor(public storage: Storage,) {

        this.socketService = Observable.create(observer => {
            this.socketObserver = observer;
        });
        
    }
    
    public initialize(user){
  
        this.user = user;

        console.log('New Socket Connection');
        
        this.socket = io.connect(this.socketHost);

        this.socket = this.socket.on("connect", (msg) => {
            console.log('Socket Connection Succeded');
            console.log(msg);

            // SEND AUTHENTIFICATION DATA
            let currentUser = {
                name: this.user.nom+' '+this.user.prenom,
                id: parseInt(this.user.id),
                type: 'ajk',
                avatar: this.user.user_picture
            };
            this.socket.emit('add user', currentUser);
        });

        this.socket.on("logged in", (msg) => {
            this.socketObserver.next({category: 'logged in', message: 'User Logged In'});
        });

        this.socket.on("reconnecting", (msg) => {
            console.log('on reconnecting');
        });

        this.socket.on("reconnect_error", (msg) => {
            console.log('on reconnect_error');
        });

        this.socket.on("reconnect_failed", (msg) => {
            console.log('on reconnect_failed');
        });

        this.socket.on('disconnect', function (msg) {
            console.log('user disconnected');
            console.log(msg);
        });

        this.socket.on("chat history", (history) => {
            console.log('chat history');
            console.log(history);
            this.socketObserver.next({category: 'history', history: history.messages});
        });

        this.socket.on("new message", (msg) => {
            this.socketObserver.next({category: 'newMessage', message: msg});
        });

        this.socket.on("receive rooms", (rooms) => {
            console.log('receive rooms');
            console.log(rooms);
            this.socketObserver.next({category: 'receiveRooms', rooms});
        });

        this.socket.on("added room", (room) => {
            console.log('added room');
            console.log(room);
            this.socketObserver.next({category: 'addedRooms', room});
        });       
    }
 
    formatUser(user){
        let currentUser = {
            name: user.nom+' '+user.prenom,
            id: parseInt(user.id),
            type: 'ajk',
            avatar: user.user_picture
        };
        return currentUser;
    }
    
    joinRoom(room_id) {
        this.socket.emit('join room', room_id); 
    }
    
    getRooms() {
        this.socket.emit('load rooms', this.user.id);
    }
    
    sendMessage(message) {
        this.socket.emit('new message', message);
        //this.socketObserver.next({ category: 'sendMessage', message: msgData });      
    }
    
    addRoom(room) {
        let roomData = {
            author_id: this.user.id,
            room_id: 2,
            name: room.name,
            private: 0,
            job_id:0
        };
        this.socket.emit('add room', roomData); 
    }


}