如何在TypeScript中正确键入RXJS WebSocket?

inkz8wg9  于 12个月前  发布在  TypeScript
关注(0)|答案(2)|浏览(135)

我有一个小服务器,我通过WebSocket与之通信,它向我发送一致的响应,我想正确地输入它。所以我在Angular中玩WebSocket,我在我的服务中有这个:

private socket$: WebSocketSubject<ResponseInterface>;

个字符
然后我在做:

const toSend: PayloadInterface = {
  sendThis: true
};
this.socket$.next(toSend);


好吧,在这个阶段,上面的代码不会用Typescript编译,因为我试图将PayloadInterface对象传递到socket中,socket是用ResponseInterface输入的。我也有监听:

public listen$(): Observable<ResponseInterface> {
   return this.socket$.asObservable();
}


1.我的问题是,我不确定应该使用哪个类型/接口来声明套接字本身。应该是ResponseInterface,因为我正在监听它,还是应该是PayloadInterface,因为我想向它推送(next)?
1.然后,我仍然会有类型冲突,要么听它,要么“下一个”到它,这取决于我在1中的选择。
我错过了什么?any/unknown没有走。

3hvapo4f

3hvapo4f1#

答案晚了,但一个变通办法,工程有点okish-是创建一个新的界面。
在本例中,它看起来像:

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,你可以添加Observable类手动实现的大重载。虽然这真的很麻烦。

kfgdxczn

kfgdxczn2#

建议你在你的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');
      });
  }
}

相关问题