UNPKG

laravel-echo

Version:

Laravel Echo library for beautiful Pusher and Socket.IO integration

165 lines (142 loc) 3.99 kB
import { Connector } from "./connector"; import { SocketIoChannel, SocketIoPrivateChannel, SocketIoPresenceChannel, } from "../channel"; import type { io, ManagerOptions, Socket, SocketOptions, } from "socket.io-client"; type AnySocketIoChannel = | SocketIoChannel | SocketIoPrivateChannel | SocketIoPresenceChannel; /** * This class creates a connector to a Socket.io server. */ export class SocketIoConnector extends Connector< "socket.io", SocketIoChannel, SocketIoPrivateChannel, SocketIoPresenceChannel > { /** * The Socket.io connection instance. */ socket: Socket; /** * All of the subscribed channel names. */ channels: { [name: string]: SocketIoChannel } = {}; /** * Create a fresh Socket.io connection. */ connect(): void { let io = this.getSocketIO(); this.socket = io( this.options.host ?? undefined, this.options as Partial<ManagerOptions & SocketOptions>, ); this.socket.io.on("reconnect", () => { Object.values(this.channels).forEach((channel) => { channel.subscribe(); }); }); } /** * Get socket.io module from global scope or options. */ getSocketIO(): typeof io { if (typeof this.options.client !== "undefined") { return this.options.client as typeof io; } if (typeof window !== "undefined" && typeof window.io !== "undefined") { return window.io; } throw new Error( "Socket.io client not found. Should be globally available or passed via options.client", ); } /** * Listen for an event on a channel instance. */ listen( name: string, event: string, callback: CallableFunction, ): AnySocketIoChannel { return this.channel(name).listen(event, callback); } /** * Get a channel instance by name. */ channel(name: string): AnySocketIoChannel { if (!this.channels[name]) { this.channels[name] = new SocketIoChannel( this.socket, name, this.options, ); } return this.channels[name]; } /** * Get a private channel instance by name. */ privateChannel(name: string): SocketIoPrivateChannel { if (!this.channels["private-" + name]) { this.channels["private-" + name] = new SocketIoPrivateChannel( this.socket, "private-" + name, this.options, ); } return this.channels["private-" + name] as SocketIoPrivateChannel; } /** * Get a presence channel instance by name. */ presenceChannel(name: string): SocketIoPresenceChannel { if (!this.channels["presence-" + name]) { this.channels["presence-" + name] = new SocketIoPresenceChannel( this.socket, "presence-" + name, this.options, ); } return this.channels["presence-" + name] as SocketIoPresenceChannel; } /** * Leave the given channel, as well as its private and presence variants. */ leave(name: string): void { let channels = [name, "private-" + name, "presence-" + name]; channels.forEach((name) => { this.leaveChannel(name); }); } /** * Leave the given channel. */ leaveChannel(name: string): void { if (this.channels[name]) { this.channels[name].unsubscribe(); delete this.channels[name]; } } /** * Get the socket ID for the connection. */ socketId(): string | undefined { return this.socket.id; } /** * Disconnect Socketio connection. */ disconnect(): void { this.socket.disconnect(); } }