From 7fa09fa6b826ca44f856b2a8cddfc50fb298a9c8 Mon Sep 17 00:00:00 2001 From: Jerko Steiner Date: Fri, 15 Nov 2019 23:38:19 -0300 Subject: [PATCH] Use TypedEmitter for client socket connections --- src/client/actions/CallActions.test.ts | 8 ++++---- src/client/actions/CallActions.ts | 3 ++- src/client/actions/PeerActions.test.ts | 5 +++-- src/client/actions/PeerActions.ts | 7 ++++--- src/client/actions/SocketActions.test.ts | 7 ++++--- src/client/actions/SocketActions.ts | 7 ++++--- src/client/socket.ts | 6 +++++- src/shared/SocketEvent.ts | 7 ++++--- src/shared/TypedEmitter.test.ts | 4 ++-- src/shared/TypedEmitter.ts | 12 +++++------- 10 files changed, 37 insertions(+), 29 deletions(-) diff --git a/src/client/actions/CallActions.test.ts b/src/client/actions/CallActions.test.ts index 8da26eb..8d03a08 100644 --- a/src/client/actions/CallActions.test.ts +++ b/src/client/actions/CallActions.test.ts @@ -46,7 +46,7 @@ describe('CallActions', () => { it('calls handshake.init when connected & got camera stream', async () => { const promise = callActions.init() - socket.emit('connect') + socket.emit('connect', undefined) await promise expect(store.getState().allActions.slice(1)).toEqual([{ type: constants.NOTIFY, @@ -73,8 +73,8 @@ describe('CallActions', () => { it('calls dispatches disconnect message on disconnect', async () => { const promise = callActions.init() - socket.emit('connect') - socket.emit('disconnect') + socket.emit('connect', undefined) + socket.emit('disconnect', undefined) expect(store.getState().allActions.slice(1)).toEqual([{ type: constants.NOTIFY, payload: { @@ -96,7 +96,7 @@ describe('CallActions', () => { it('dispatches alert when failed to get media stream', async () => { (getUserMedia as any).fail(true) const promise = callActions.init() - socket.emit('connect') + socket.emit('connect', undefined) await promise }) diff --git a/src/client/actions/CallActions.ts b/src/client/actions/CallActions.ts index 3201db0..8b8ba61 100644 --- a/src/client/actions/CallActions.ts +++ b/src/client/actions/CallActions.ts @@ -2,6 +2,7 @@ import * as constants from '../constants' import socket from '../socket' import { Dispatch, ThunkResult } from '../store' import { callId, getUserMedia } from '../window' +import { ClientSocket } from '../socket' import * as NotifyActions from './NotifyActions' import * as SocketActions from './SocketActions' import * as StreamActions from './StreamActions' @@ -34,7 +35,7 @@ async (dispatch, getState) => { } export const connect = () => (dispatch: Dispatch) => { - return new Promise(resolve => { + return new Promise(resolve => { socket.once('connect', () => { resolve(socket) }) diff --git a/src/client/actions/PeerActions.test.ts b/src/client/actions/PeerActions.test.ts index b41895f..91441d7 100644 --- a/src/client/actions/PeerActions.test.ts +++ b/src/client/actions/PeerActions.test.ts @@ -7,15 +7,16 @@ import { EventEmitter } from 'events' import { createStore, Store, GetState } from '../store' import { play } from '../window' import { Dispatch } from 'redux' +import { ClientSocket } from '../socket' describe('PeerActions', () => { function createSocket () { - const socket = new EventEmitter() as unknown as SocketIOClient.Socket + const socket = new EventEmitter() as unknown as ClientSocket socket.id = 'user1' return socket } - let socket: SocketIOClient.Socket + let socket: ClientSocket let stream: MediaStream let user: { id: string } let store: Store diff --git a/src/client/actions/PeerActions.ts b/src/client/actions/PeerActions.ts index 502dcbb..65dab1c 100644 --- a/src/client/actions/PeerActions.ts +++ b/src/client/actions/PeerActions.ts @@ -7,6 +7,7 @@ import forEach from 'lodash/forEach' import _debug from 'debug' import { play, iceServers } from '../window' import { Dispatch, GetState } from '../store' +import { ClientSocket } from '../socket' const debug = _debug('peercalls') @@ -15,14 +16,14 @@ export interface Peers { } export interface PeerHandlerOptions { - socket: SocketIOClient.Socket + socket: ClientSocket user: { id: string } dispatch: Dispatch getState: GetState } class PeerHandler { - socket: SocketIOClient.Socket + socket: ClientSocket user: { id: string } dispatch: Dispatch getState: GetState @@ -94,7 +95,7 @@ class PeerHandler { } export interface CreatePeerOptions { - socket: SocketIOClient.Socket + socket: ClientSocket user: { id: string } initiator: string stream?: MediaStream diff --git a/src/client/actions/SocketActions.test.ts b/src/client/actions/SocketActions.test.ts index 735a5b6..6adaee4 100644 --- a/src/client/actions/SocketActions.test.ts +++ b/src/client/actions/SocketActions.test.ts @@ -6,12 +6,13 @@ import * as constants from '../constants' import Peer from 'simple-peer' import { EventEmitter } from 'events' import { createStore, Store, GetState } from '../store' +import { ClientSocket } from '../socket' import { Dispatch } from 'redux' describe('SocketActions', () => { const roomName = 'bla' - let socket: SocketIOClient.Socket + let socket: ClientSocket let store: Store let dispatch: Dispatch let getState: GetState @@ -67,7 +68,7 @@ describe('SocketActions', () => { it('should forward signal to peer', () => { socket.emit('signal', { userId: 'b', - data, + signal: data, }) expect(instances.length).toBe(1) @@ -77,7 +78,7 @@ describe('SocketActions', () => { it('does nothing if no peer', () => { socket.emit('signal', { userId: 'a', - data, + signal: data, }) expect(instances.length).toBe(1) diff --git a/src/client/actions/SocketActions.ts b/src/client/actions/SocketActions.ts index f164465..27913a1 100644 --- a/src/client/actions/SocketActions.ts +++ b/src/client/actions/SocketActions.ts @@ -5,11 +5,12 @@ import keyBy from 'lodash/keyBy' import _debug from 'debug' import { SignalData } from 'simple-peer' import { Dispatch, GetState } from '../store' +import { ClientSocket } from '../socket' const debug = _debug('peercalls') export interface SocketHandlerOptions { - socket: SocketIOClient.Socket + socket: ClientSocket roomName: string stream?: MediaStream dispatch: Dispatch @@ -27,7 +28,7 @@ export interface UsersOptions { } class SocketHandler { - socket: SocketIOClient.Socket + socket: ClientSocket roomName: string stream?: MediaStream dispatch: Dispatch @@ -70,7 +71,7 @@ class SocketHandler { } export interface HandshakeOptions { - socket: SocketIOClient.Socket + socket: ClientSocket roomName: string stream?: MediaStream } diff --git a/src/client/socket.ts b/src/client/socket.ts index 3d6a3e0..4b3a92d 100644 --- a/src/client/socket.ts +++ b/src/client/socket.ts @@ -1,3 +1,7 @@ import SocketIOClient from 'socket.io-client' import { baseUrl } from './window' -export default SocketIOClient('', { path: baseUrl + '/ws' }) +import { TypedEmitterKeys, SocketEvent, TypedEmitter } from '../shared' +export type ClientSocket = Omit & + TypedEmitter +const socket: ClientSocket = SocketIOClient('', { path: baseUrl + '/ws' }) +export default socket diff --git a/src/shared/SocketEvent.ts b/src/shared/SocketEvent.ts index 1014233..9e7b5ce 100644 --- a/src/shared/SocketEvent.ts +++ b/src/shared/SocketEvent.ts @@ -11,10 +11,11 @@ export interface SocketEvent { } signal: { userId: string - signal: unknown + // eslint-disable-next-line + signal: any } - connect: void - disconnect: void + connect: undefined + disconnect: undefined ready: string } diff --git a/src/shared/TypedEmitter.test.ts b/src/shared/TypedEmitter.test.ts index 11b93c8..4fe0eb6 100644 --- a/src/shared/TypedEmitter.test.ts +++ b/src/shared/TypedEmitter.test.ts @@ -38,12 +38,12 @@ describe('TypedEmitter', () => { let emitter: TypedEmitter beforeEach(() => { emitter = new EventEmitter() - emitter.addListener('test1', listener1) + emitter.on('test1', listener1) emitter.on('test2', listener2) emitter.once('test3', listener3) }) - describe('addListener & on', () => { + describe('on & on', () => { it('adds an event emitter', () => { emitter.emit('test1', 'value') emitter.emit('test2', 3) diff --git a/src/shared/TypedEmitter.ts b/src/shared/TypedEmitter.ts index f761220..c0add9d 100644 --- a/src/shared/TypedEmitter.ts +++ b/src/shared/TypedEmitter.ts @@ -1,21 +1,19 @@ -import { EventEmitter } from 'events' - type Callback = (a: A) => void // eslint-disable-next-line type Events = Record export type TypedEmitterKeys = - 'addListener' | 'removeListener' | 'on' | 'once' | 'off' | 'emit' -export interface TypedEmitter -extends EventEmitter { - addListener(t: K, callback: Callback): this +// Some methods might be missing and we do not extend EventEmitter because +// SocketIOClient.Socket does not inherit from EventEmitter, and the method +// signatures differ slightly. +export interface TypedEmitter { removeListener(t: K, callback: Callback): this on(t: K, callback: Callback): this @@ -23,5 +21,5 @@ extends EventEmitter { off(t: K, callback: Callback): this - emit(t: K, value: E[K]): boolean + emit(t: K, value: E[K]): void }