如何在TypeScript中正确地输入RXJS WebSocket?

3

我有一个小服务器,通过WebSocket与其通信,它会发送一致的响应,因此我想要正确地输入它。所以我在Angular中尝试使用WebSockets,并在我的服务中添加了以下内容:

private socket$: WebSocketSubject<ResponseInterface>;

private createSocket$(): WebSocketSubject<ResponseInterface> {
  return webSocket({
      url: 'localhost:2343'
  });
}

然后我正在做:
const toSend: PayloadInterface = {
  sendThis: true
};
this.socket$.next(toSend);

好的,目前这段代码在使用Typescript编译时会出错,因为我试图将PayloadInterface对象传递到已经使用ResponseInterface类型的socket中。此外,我还有监听器:

public listen$(): Observable<ResponseInterface> {
   return this.socket$.asObservable();
}
  1. 我的问题是,我不确定应该使用哪种类型/接口来声明套接字本身。应该使用ResponseInterface,因为我正在监听它,还是应该使用PayloadInterface,因为我想要推送(next)到它?
  2. 然后,无论我在第1步中选择什么,我仍然会遇到类型冲突,无论是监听它还是“next”到它。

我错过了什么? any/unknown不可行。


不确定我理解你的意思:https://stackblitz.com/edit/rxjs-jzf67z?devtoolsheight=60 - undefined
1
@enno.void 谢谢,看来你正确理解了我的问题。将两个接口的字段合并成一个是有趣的,我可以考虑一下,但这仍然是一个变通方法。我想知道是否有更好的方法来做到这一点。目前我还有这样的代码:(this.socket$ as unknown as Subject<PayloadInterface>).next(value); 而我的 socket$ 是定义为 WebSocketSubject<ResponseInterface>。 - undefined
2个回答

0
晚回答,但有一个勉强可行的解决方法-创建一个新的接口。
在这种情况下,它会看起来像这样:
interface WS<T,K> extends WebSocketSubject<T | K> {
  next(value: K): void;
  asObservable(): Observable<T>;
}

那么,对于OP的情况,使用方法应该是:
private createSocket$(): WS<ResponseInterface, PayloadInterface > {
  return webSocket({
      url: 'localhost:2343'
  }) as WS<ResponseInterface, PayloadInterface>; // really annoying to need this though.
}

使用这个方法,其他功能应该可以正常工作,无需添加任何内容。 这种解决方案的一个缺点是直接在websocket上使用pipe。个人而言,我只在asObservable的输出上使用pipe。但是,如果需要在socket上直接使用pipe,你可以手动添加Observable类实现的大量重载。不过,这真的很繁琐。

-2
建议您在Angular应用程序中使用socket.io-client的类型定义。然后按照以下方式定义一个服务:
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Observer } from 'rxjs/Observer';
import { Message } from '../model/message';
import { Event } from '../model/event';

import * as socketIo from 'socket.io-client';

const SERVER_URL = 'https://yourserverhost.com';

@Injectable()
export class SocketService {
    private socket;

    public initSocket(): void {
        this.socket = socketIo(SERVER_URL);
    }

    public send(message: Message): void {
        this.socket.emit('message', message);
    }

    public onEvent(event: Event): Observable<any> {
        return new Observable<Event>(observer => {
            this.socket.on(event, () => observer.next());
        });
    }
}

定义一个事件枚举:
export enum Event {
    CONNECT = 'connect',
    DISCONNECT = 'disconnect'
}
Then subscribe to your service functions from your Angular component:

export class ChatComponent implements OnInit {
  constructor(private socketService: SocketService) { }

   ngOnInit(): void {
    this.initIoConnection();
  }

  private initIoConnection(): void {
    this.socketService.initSocket();

    this.ioConnection = this.socketService.onMessage()
      .subscribe((message: Message) => {
        this.messages.push(message);
      });


    this.socketService.onEvent(Event.CONNECT)
      .subscribe(() => {
        console.log('Connected to the server');
      });

    this.socketService.onEvent(Event.DISCONNECT)
      .subscribe(() => {
        console.log('Disconnected');
      });
  }
}

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