如何在使用node.js的angular中使用socket.io?

3

我使用了Angular 6作为客户端,Node.js作为服务器端。

在Angular 6中,使用以下代码后,在控制台中打印消息和socket.io id({message: "Hello World", id: "6An-ctwlwbZZWrfMAAAB"})

请问这段代码正确吗?如果不确定,请帮忙改正。

另外一个问题是,我的项目中有15个以上的组件,如何让所有组件都可以共用socket.io?我需要在所有其他组件中导入app.component.ts代码吗?

服务器端的代码为app.js。

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));
    }
  }
}

1
请查看此链接:https://blog.codewithdan.com/pushing-real-time-data-to-an-angular-service-using-web-sockets/ - undefined
你有收到任何错误吗? - undefined
我在谷歌浏览器中没有看到任何错误控制台输出,就像这样({message: "Hello World", id: "6An-ctwlwbZZWrfMAAAB"})。但是我有超过15个组件,所以我不知道如何在所有组件中使用socket.io通用方法。你告诉我要创建一个服务来处理这个问题,但是通过服务如何在所有组件中获取socket.io的Angular到Node的连接呢? - undefined
你能试试我的示例代码吗? - undefined
我正在尝试,我不知道这是服务中的什么,导入{ Socket } from '../shared/interfaces'; - undefined
Ref:https://www.typescriptlang.org/docs/handbook/interfaces.html - undefined
3个回答

8

实现这种机制的一种方法是使用ngx-socket-io,在模块级别或根级别连接你的Node服务器,我已经以下面的代码实现

app.module.ts 代码

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 { }

创建一个服务来处理您的进出流量。
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);
}
}

在你的组件文件中更新你的代码

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);
 }
}

getMessage() { return this.socket .fromEvent<any>('msg') .map(data => data.msg); } 这段代码在.map处出现了错误。 - undefined
请解决以下与编程相关的内容:请在链接中解决:https://stackoverflow.com/questions/59872472/how-to-resolve-this-map-error-in-socket-programming-angular - undefined
你使用的 Angular 版本是哪个? - undefined
我正在使用Angular 7。 - undefined
如何在这个示例中添加Bearer令牌?配置在appmodule中,但是Bearer令牌可能稍后在其他模块中可用,如何将其添加到每个请求中。 - undefined

3
创建服务并将套接字数据转换为可观察流。
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);
  }
}

然后从组件中调用

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 = '';
  }
}

2
您可以创建一个用于处理套接字的服务。例如(当然,这只是一个非常简单的示例):
/* 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;
        }
    }
}

并在任何组件中使用它:

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();
    }
}

从'app/shared/io/io.service'导入{ SocketService,IOEventName,IEventName1Message,IEventName2Message }。 如何导入这个?我的node.js代码是正确的吗? - undefined
@AmishaRana app/shared/io/io.service 是我示例的第一个代码块。它是 Angular 代码。 - undefined
这个例子不错,但可以改进。为什么在"onEvent"函数中每次都返回一个新的Observable?因为这个函数可以被多个组件使用。你应该只创建一个IOEventName的Observable。 initSocket不太好,initSocket应该是服务的构造函数。你不应该为相同的URL打开两个socket。 - undefined
@xrobert35 你说得对。这只是一个简单的例子,可以改进。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接