File size: 2,635 Bytes
cccfc29
 
 
 
 
 
 
 
 
 
 
 
 
 
502af73
 
 
 
 
 
 
 
 
 
 
 
 
 
cccfc29
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
502af73
 
 
 
 
 
 
 
 
cccfc29
502af73
cccfc29
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import { ref, onUnmounted } from "vue";
import { io, Socket } from "socket.io-client";

// Singleton socket instance
let socketInstance: Socket | null = null;

export function useSocket() {
	const connected = ref(false);
	const error = ref<string | null>(null);

	// Get or create socket instance
	const getSocket = (): Socket => {
		if (!socketInstance) {
			// Determine the server URL based on environment
			const isDev = import.meta.env?.DEV ?? import.meta.env?.MODE === "development";

			let serverUrl: string;
			if (isDev) {
				// Development: Use same host as frontend, port 3000
				// This allows accessing from local IP (e.g., 192.168.x.x:5173)
				const currentHost = window.location.hostname;
				serverUrl = `http://${currentHost}:3000`;
			} else {
				// Production: same origin
				serverUrl = window.location.origin;
			}

			console.log("[Socket.io] Connecting to:", serverUrl);

			socketInstance = io(serverUrl, {
				autoConnect: true,
				reconnection: true,
				reconnectionDelay: 1000,
				reconnectionAttempts: 5
			});

			// Connection event handlers
			socketInstance.on("connect", () => {
				connected.value = true;
				error.value = null;
				console.log("[Socket.io] Connected:", socketInstance?.id);
			});

			socketInstance.on("disconnect", (reason) => {
				connected.value = false;
				console.log("[Socket.io] Disconnected:", reason);
			});

			socketInstance.on("connect_error", (err) => {
				error.value = err.message;
				console.error("[Socket.io] Connection error:", err.message);
			});
		}

		return socketInstance;
	};

	// Send echo test message
	const sendEcho = (message: string): Promise<string> => {
		return new Promise((resolve, reject) => {
			const socket = getSocket();

			if (!socket.connected) {
				reject(new Error("Socket not connected"));
				return;
			}

			// Send echo request and wait for response
			socket.emit(
				"echo",
				{ message, timestamp: new Date().toISOString() },
				(response: any) => {
					if (response.error) {
						reject(new Error(response.error));
					} else {
						resolve(response.message);
					}
				}
			);

			// Timeout after 5 seconds
			setTimeout(() => {
				reject(new Error("Echo request timeout"));
			}, 5000);
		});
	};

	// Clean up on unmount
	onUnmounted(() => {
		// Note: We don't disconnect the singleton instance
		// It will be reused by other components
	});

	return {
		socket: getSocket(),
		connected,
		error,
		sendEcho
	};
}

// Export function to manually disconnect (for cleanup)
export function disconnectSocket() {
	if (socketInstance) {
		socketInstance.disconnect();
		socketInstance = null;
	}
}