angular2-webpack-starterにsocketioを追加してみる


angular2-webpack-starter

ここに説明がある angular2 starter  /  リポジトリ repository

ファイルの追加

赤字を追加、青字を編集。

  • angular2-webkit-starter
  • server
    • server.js
  • src
    • app
      • +barrel
      • +detail
      • about
      • sockets
        • index.ts
        • sockets.service.ts
      • home
      • no-content
      • app.component.css
      • app.component.spen.css
      • app.component.ts
      • app.e2d.ts
      • app.module.ts
      • app.resolver.ts
      • app.routes.ts
      • environmemt.ts
      • index.ts

npm moduleの追加

  • webpack-hot-middleware
  • socket.io-client
  • @type/socket.io-client
npm install webpack-hot-middleware --savedev
npm install socket.io-client --save
npm install @type/socket.io-client --savedev

server.jsの追加

server/server.js


const http = require('http');
const express = require('express');

const webpack = require('webpack');
const webpackConfig = require('../webpack.config.js');
const compiler = webpack(webpackConfig);

const app = express();
app.use(require('webpack-dev-middleware')(compiler, {
  noInfo: true,
  publicPath: webpackConfig.output.publicPath,
}));
app.use(require('webpack-hot-middleware')(compiler));
app.use(express.static('dist'));
const server = new http.Server(app);
const PORT = process.env.PORT || 3000;

server.listen(PORT);

/*
 socketio
*/
var io = require('socket.io')(server);
io.on('connection', function(socket){    
  socket.on('socketTest', function(){
    console.log('getEmmit!!!');
    socket.emit('retSocketTest');
  });
});

socket serviceの追加(/app/shared)

index.ts, socket.service.ts

index.tsの追加

export * from './sockets.component';
socket.service.tsの追加

import { Injectable, OnDestroy } from "@angular/core";
import * as io from "socket.io-client";

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

    constructor() {
        this.socket = io.connect();
        this.socket.on('retSocketTest', () => {
            console.log('retSocketTest');
        })
    }
    public test(){
        this.socket.emit('socketTest');
    }
    public ngOnDestroy() {
        console.log('socketio close');
        this.socket.close();
    }
}

socketsコンポーネントの追加(/app/sockets)

index.ts, sockets.component.ts

index.tsの追加

export * from './sockets.component';
sockets.component.tsの追加

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { SocketService } from '../shared';

@Component({
  selector: 'sockets',
  providers: [ SocketService ],
  template:`
    <h1>Sockets</h1>
  `
})
export class SocketsComponent implements OnInit {
  private socketData : any;
  constructor( private socketService: SocketService ){
  }
  public ngOnInit(){
    console.log('sockets');
    this.socketService.test();    
  }
}

app.componentコンポーネントの修正(/app)

app.module.ts, app.route.ts, app.component.ts

app.module.tsの修正
SocketComponentをngModuleに追加
//追加
import { SocketComponent } from './sockets';

@NgModule({ bootstrap: [ AppComponent ],
declarations: [
...

SocketsComponent
],

赤字を追加
app.route.tsの修正
socket.componentのrouteを追加
//追加
import { SocketsComponent } from './sockets';

export const ROUTES: Routes = [ ...
{ path: 'sockets', component: SocketsComponent }, <<< 追加


//---------------
path :'**'より下に追加すると、ルーティングされない。
app.component.tsの修正
@Component({
template: `
<nav>
...
//追加
<a [routerLink]=" ['./sockets'] "
routerLinkActive="active" [routerLinkActiveOptions]= "{exact: true}">
Sockets
</a>
...
これで、socketsページを表示すると、 クライアントからサーバに'socketTest'がemitされ、 サーバから、'retSocketTest'が返送される。


ここまでで、socketioが追加できた。


サーバ側にmongodbを追加する。 socket.componentでmongodbデータを取得できるようにする。

ファイルの追加

赤字を追加、青字を編集。

  • angular2-webkit-starter
  • server
    • server.js
  • src
    • models
      • index.ts
      • sockets-item.model.ts
    • app
      • +barrel
      • +detail
      • about
      • sockets
        • index.ts
        • sockets.service.ts
      • home
      • no-content
      • app.component.css
      • app.component.spen.css
      • app.component.ts
      • app.e2d.ts
      • app.module.ts
      • app.resolver.ts
      • app.routes.ts
      • environmemt.ts
      • index.ts

npm moduleの追加

  • mongodb
npm install mongodb --save

server.jsにmongodb追加

server/server.js

socketio部にmongodbを追加して置き換え

/*
 socketio
*/
var io = require('socket.io')(server);
/*
 mongodb
*/
var Promise = require("bluebird");
var MongoDB = Promise.promisifyAll(require("mongodb"));
var MongoClient = Promise.promisifyAll(MongoDB.MongoClient);
var MONGO_URL = 'mongodb://127.0.0.1:27017/test';

io.on('connection', function(socket){    
  socket.on('socketTest', function(){
    console.log('getEmmit!!!');
    socket.emit('retSocketTest');
  });
  socket.on('mongoRead', function(){
    console.log('getEmmit!!!');
    MongoClient.connectAsync('mongodb://localhost:27017/myTest').then(function(db) {
      return db.collection("myTest").find({}).toArrayAsync();
    }).then(function(orders) {
      console.log('then1', orders);
      socket.emit('retMongoRead', orders);
    }).catch(function(err) {
      console.log('then2', err);
    });
  });
});

socket service用のmodelの追加

index.ts, socket-item.model.ts

src/modelsフォルダを作成して、ファイルを追加する。
index.tsの追加

export * from "./socket-item.model";
socket-item.model.tsの追加

export interface ISocketItem {
    action: string;
    item: any;
}

socket.service/socket.componentsの変更

index.ts, socket.service.ts

socket.onをovserveし、socket.componetsでscribeして読む。
socket.serviceの変更

import { Injectable, OnDestroy } from "@angular/core";
import { Observable } from "rxjs";
import * as io from "socket.io-client";
import { ISocketItem } from "../../models";

@Injectable()
export class SocketService implements OnDestroy{
    private socket: SocketIOClient.Socket;
    private mongoData: any;

    constructor() {
        //this.socket = io.connect();
        this.socket = io.connect();
    }
    public get(): Observable{
        return Observable.create((observer: any) => {
            this.socket.on("retSocketTest", (item: any) => observer.next({ action: "test", item: item }) );
            this.socket.on("retMongoRead", (item: any) => observer.next({ action: "read", item: item }) );
            return () => this.socket.close();
        });
    }
    public test(){
        this.socket.emit('socketTest');
    }
    public ngOnDestroy() {
        console.log('socketio close');
        this.socket.close();
    }
    public mongoRead() {
        this.socket.emit('mongoRead');
    }
}

socket-item.model.tsの追加

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { SocketService } from '../shared';
import { ISocketItem } from "../../models";
import { Observable } from "rxjs";

@Component({
  selector: 'sockets',
  providers: [ SocketService ],
  template:`
    <h1>Sockets</h1>
    <button (click)=mongoRead()>mongoRead</button>
    {{ mongoReadData | json}}
    <br><br>
  `
})
export class SocketsComponent implements OnInit {
  private socketData : any;
  private mongoReadData : any;
  constructor( private socketService: SocketService ){
    this.mongoReadData = {};
    this.socketService.get()
      .subscribe(
                (socketItem: ISocketItem) => {
                  /*
                    let message: IMessage = socketItem.item;
                    this.list = this.list.push(message);
                    this.messages.next(this.list);
                    */
                    if(socketItem.action === 'test'){
                      console.log('test', socketItem.item);
                    }
                    else if(socketItem.action === 'read'){
                      console.log('read', socketItem.item);
                      this.mongoReadData = socketItem.item;
                    }
                    //this.mongoReadData.next();
                },
                error => console.log(error)
            );
  }
  public ngOnInit(){
    console.log('sockets');
    this.socketService.test();    
  }
  private mongoRead(){
    console.log('btn click');
    this.socketService.mongoRead();
  }
}


socketsページ

socketMongoRead

こんな感じにsocketsページでmongoReadボタンを押すと、dbのmongoデータが表示される。