如何在 node.js 中以角度使用 socket.io?
Posted
技术标签:
【中文标题】如何在 node.js 中以角度使用 socket.io?【英文标题】:How to use socket.io in angular with node.js? 【发布时间】:2019-03-05 02:44:39 【问题描述】:客户端我使用 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(客户端)
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));
【问题讨论】:
检查这个:blog.codewithdan.com/… 你有什么错误吗? 不,我没有像这样在 crome 浏览器中收到任何错误控制台打印 (message: "Hello World", id: "6An-ctwlwbZZWrfMAAAAB") 但我有超过 15 个组件所以我不知道如何使用所有组件通用的 socket.io,你告诉我为此提供服务,但使用服务如何获取所有组件的 socket.io 角度到节点 你能试试我的示例代码吗 我正在尝试,我不知道从 '../shared/interfaces' 的服务导入 Socket 中这是什么; 【参考方案1】:实现此机制的一种方法是使用ngx-socket-io
,在模块级别或根级别连接您的节点服务器,如下所示
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('msg') .map(data => data.msg); 这给了我 .map 中的错误 请在链接解决:***.com/questions/59872472/… 你使用的是什么版本的角度? 我正在使用 Angular 7 本例中如何添加不记名令牌?配置在appmodule中,但是bearer稍后可以在其他模块中使用,如何将其添加到每个请求中。【参考方案2】:创建服务并将您的套接字数据转换为 Observable 流
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 = '';
【讨论】:
【参考方案3】:您可以创建一个使用套接字的服务。例如(当然这是一个非常简单的例子):
/* 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 代码是对的吗? @AmishaRanaapp/shared/io/io.service
是我示例的第一个代码块。是角码。
这个例子很好,但可以改进。为什么每次在“onEvent”函数中返回一个新的 Observable ?由于此功能可以被许多组件使用。您应该只通过 IOEventName 创建一个。 initSocket 不是很好,initSocket 应该是服务构造器。您不应该为同一个 url 打开两个套接字。
@xrobert35 你是对的。这是一个简单的例子,可以改进。以上是关于如何在 node.js 中以角度使用 socket.io?的主要内容,如果未能解决你的问题,请参考以下文章
如何将 Asterisk ARI 与 socket.io 和 Node.js 一起使用
如何在 node.js 中接收 socket.io 客户端事件?
如何使用 Socket.io 和 Node.js 开发大型聊天应用程序 [关闭]