각도 2는 여러 구성 요소에 걸쳐 웹 소켓 서비스를 공유함
나는 같은 서비스를 듣는 여러 구성 요소를 원하는 각도 2를 이용하여 웹 애플리케이션을 만들고 있어.이 서비스는 웹세트에서 들어오는 데이터를 반환하는 관측 가능한 데이터를 반환한다.나는 이 예시를 근거로 코드를 작성했다.
현재 문제는 다음과 같다.서비스를 통해 홈 컴포넌트에서 서버로 데이터를 전송(웹사이트 사용)하고 데이터를 반환한다.그러나, Navbar에 있는 것이 아니라, 가정.구성요소에 있는 관찰자만 (ID: room.created and data)로 호출되고 있다.
왜 둘 다 부르지 않는지 누가 말해줄래?message$.subscribe도 app.component에 추가하려고 했지만 소용이 없었다.
자, 이제 암호로 들어가자.
관찰 가능한 메시지를 반환하는 메시지 서비스.이 서비스는 메시지 송수신을 위해 구성 요소에 의해 사용된다.
@Injectable()
export class MessageService {
private _messages: Rx.Subject<Message>;
messages$: Rx.Observable<Message>;
constructor(wsService: SocketService, private configuration: Configuration) {
console.log('messag eservice');
this._messages = <Rx.Subject<Message>>wsService
.connect()
.map((response: MessageEvent): Message => {
let data = JSON.parse(response.data);
return {
id: data.id,
data: data.data,
}
});
this.messages$ = this._messages.asObservable();
}
public send(message: Message): void {
this._messages.next(message);
}
}
웹 소켓 연결을 생성하고 이 소켓의 입력과 출력에 자체 바인딩하는 소켓 서비스.
import { Injectable } from '@angular/core';
import * as Rx from "rxjs/Rx";
import { Configuration } from '../app.constants';
@Injectable()
export class SocketService {
private subject: Rx.Subject<MessageEvent>;
constructor(private configuration: Configuration){};
public connect(wsNamespace = ''): Rx.Subject<MessageEvent> {
var url = this.configuration.wsUrl + wsNamespace;
if(!this.subject) {
this.subject = this.create(url);
}
return this.subject;
}
private create(url): Rx.Subject<MessageEvent> {
let ws = new WebSocket(url);
// bind ws events to observable (streams)
let observable = Rx.Observable.create((obs: Rx.Observer<MessageEvent>) => {
ws.onmessage = obs.next.bind(obs);
ws.onerror = obs.error.bind(obs);
ws.onclose = obs.complete.bind(obs);
return ws.close.bind(ws);
});
// on obs next (send something in the stream) send it using ws.
let observer = {
next: (data: Object) => {
if (ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify(data));
}
},
};
return Rx.Subject.create(observer, observable);
}
}
다음 공급자가 있는 앱 구성 요소:
providers: [MessageService, SocketService, Configuration, AuthService]
메시지 및 소켓 서비스가 두 번 인스턴스화되지 않도록 주 app.component의 제공자를 인스턴스화하고 있다.
내 home.component는 다음과 같이 생겼다(이 페이지는 라우팅 기능을 사용하여 로드되는 페이지임).
import { Component, OnInit } from '@angular/core';
import { Subject } from 'rxjs';
import { Router } from '@angular/router';
import { MessageService } from '../../services/message.service';
@Component({
...
providers: []
})
export class HomeComponent implements OnInit {
constructor(private router: Router, private messageService: MessageService) {}
ngOnInit(): void {
this.messageService.send({
id: 'room.create',
data: {'name': 'Blaat'}
});
this.messageService.messages$.subscribe(msg => {
console.log(msg);
if(msg.id == 'room.created') {
// navigate naar games!
}
});
}
}
내 내비게이션 바 구성 요소는 다음과 같음(다이렉트):
import { Component, OnInit } from '@angular/core';
import { MessageService } from '../../services/message.service';
@Component({
moduleId: module.id,
selector: 'navbar',
templateUrl: 'navbar.component.html',
styleUrls: ['navbar.component.css']
})
export class Navbar implements OnInit {
constructor(private messageService: MessageService) { }
ngOnInit() {
this.messageService.messages$.subscribe(msg => {
console.log(msg);
if(msg.id == 'room.created') {
// navigate naar games!
}
});
}
}
관측 가능한 생성 함수를 여러 번 호출하는 것 같은데, 대부분 두 개의 구성 요소 => 두 개의 구독 => 두 개의 관측 가능한 생성 함수 호출.그래서 최근에 관찰할 수 있는 create fn은 이전의 관찰 가능한 callback을 message, onerror, close에 웹소켓으로 재정의한다.당신은 그것을 막기 위해 관찰할 수 있는 기본적인 멀티캐스트를 해야 한다. (공유 운영자는 그 트릭을 해야 한다.)
// bind ws events to observable (streams)
let observable = Rx.Observable.create((obs: Rx.Observer<MessageEvent>) => {
ws.onmessage = obs.next.bind(obs);
ws.onerror = obs.error.bind(obs);
ws.onclose = obs.complete.bind(obs);
return ws.close.bind(ws);
}).share();
이 작업을 올바르게 수행하는 방법에 대한 더 유용한 리소스 https://github.com/ReactiveX/rxjs/blob/master/src/observable/dom/WebSocketSubject.ts
서비스를 사용하여 각도에 대해 암호화된 요청을 보내고 암호화된 응답을 가져오려면 아래 코드를 해독하십시오.
mycomponent.ts 파일 :::
import { Component, TemplateRef, OnInit, ViewChild } from '@angular/core';
import { myService } from 'src/app/my.service';
import { Base64 } from 'js-base64';
import { SelectItem } from 'primeng/api';
import { ActivatedRoute, Router } from '@angular/router';
getDataFromService() {
this._myService.getData("api_name/url")
.subscribe(data => {
let myResp = Base64.decode(this.myData = data);
this.myResponse = JSON.parse(myResp );
}
myservice.ts 파일 :::
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
import { Observable } from 'rxjs';
import { Iwatchlist } from './watchlist';
import { Base64 } from 'js-base64';
private _url: string = "http://192.168.10.10:1000";
getData(svcName): Observable<any> {
let baseUrl= this._url + "/"+svcName;
const httpOptions = {
headers: { 'Content-Type': 'application/json' },
"request": {
"FormFactor": "M",
"svcGroup": "portfolio",
"svcVersion": "1.0.0",
"svcName": svcName,
"requestType": "U",
"data": {
"gcid": "123",
"gscid": "abc123"
}
}
};
let encryptedData = Base64.encode(JSON.stringify(httpOptions));
let postRequest = this.http.post(baseUrl, encryptedData, {responseType: 'text'});
return postRequest;
}
참조URL: https://stackoverflow.com/questions/39183793/angular-2-share-websocket-service-across-components
'programing' 카테고리의 다른 글
기본 인코딩이 ASCII인데 Python이 유니코드 문자를 인쇄하는 이유는? (0) | 2022.03.17 |
---|---|
setup.py이란 무엇인가? (0) | 2022.03.17 |
기본 일시 중지/재생 GIF 반응 (0) | 2022.03.17 |
Vue 2 및 웹 팩과 조인트 j를 통합하는 방법 (0) | 2022.03.17 |
VUE: Imgs에 글로벌 변수 사용 (0) | 2022.03.17 |