Skip to content

Commit 84922c7

Browse files
committed
refactor: update state management types and improve connection handling in chat services
1 parent 92ac1a5 commit 84922c7

File tree

6 files changed

+113
-75
lines changed

6 files changed

+113
-75
lines changed

src/services/groupChatService.ts

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
import { Chat, GroupChat } from '@/types/chat'
22
import { EventEmitter } from '@/utils/eventEmitter'
33
import { cleanRoomId } from '@/utils/roomUtils'
4+
import { ChatState, SetStateFunction, GetStateFunction } from '@/types/store'
45
import { MessageService } from './messageService'
56
import { PeerService } from './peerService'
67

7-
// 定义状态更新函数类型
8-
type SetFunction = (partial: Partial<any> | ((state: any) => Partial<any>)) => void
9-
type GetFunction = () => any
10-
118
export class GroupChatService {
129
constructor(
13-
private set: SetFunction,
14-
private get: GetFunction,
10+
private set: SetStateFunction<ChatState>,
11+
private get: GetStateFunction<ChatState>,
1512
private chatEvents: EventEmitter,
1613
private peerService: PeerService,
1714
private messageService: MessageService
@@ -46,11 +43,11 @@ export class GroupChatService {
4643
shareLink: `${window.location.origin}${window.location.pathname}?roomId=${groupId}`,
4744
// 添加局域网相关信息
4845
isLocalNetwork: isLocalNetwork,
49-
localIpAddress: localIpAddress
46+
localIpAddress: localIpAddress || undefined
5047
}
5148

5249
// 添加系统消息
53-
let systemMessage = this.messageService.addSystemMessage(`群聊已创建,分享链接邀请好友加入吧!\n群聊ID: ${groupId}\n\n请确保在群聊保持活跃状态,否则连接可能会过期。`)
50+
const systemMessage = this.messageService.addSystemMessage(`群聊已创建,分享链接邀请好友加入吧!\n群聊ID: ${groupId}\n\n请确保在群聊保持活跃状态,否则连接可能会过期。`)
5451

5552
if (groupChat.messages) {
5653
groupChat.messages.push(systemMessage)
@@ -82,7 +79,7 @@ export class GroupChatService {
8279
}
8380

8481
// 如果是群主,向所有连接发送心跳
85-
if (currentChat.isHost) {
82+
if (currentChat.isGroup && (currentChat as GroupChat).isHost) {
8683
const { connections } = this.get()
8784
if (Object.keys(connections).length > 0) {
8885
console.log(`发送心跳到 ${Object.keys(connections).length} 个连接`)
@@ -159,7 +156,7 @@ export class GroupChatService {
159156
serialization: 'json',
160157
metadata: {
161158
isLocalNetwork,
162-
localIpAddress: connectionInfo.localIpAddress,
159+
localIpAddress: connectionInfo.localIpAddress || undefined,
163160
userName: userName,
164161
peerId: peer.id,
165162
timestamp: new Date().toISOString() // 添加时间戳
@@ -216,7 +213,7 @@ export class GroupChatService {
216213
isHost: false,
217214
shareLink: `${window.location.origin}${window.location.pathname}?roomId=${cleanedRoomId}`,
218215
isLocalNetwork: isLocalNetwork,
219-
localIpAddress: connectionInfo.localIpAddress
216+
localIpAddress: connectionInfo.localIpAddress || undefined
220217
}
221218

222219
console.log('创建新的群聊对象:', newGroupChat)
@@ -243,7 +240,7 @@ export class GroupChatService {
243240
id: peer.id,
244241
name: userName,
245242
isLocalNetwork: isLocalNetwork,
246-
localIpAddress: connectionInfo.localIpAddress
243+
localIpAddress: connectionInfo.localIpAddress || undefined
247244
}
248245
})
249246

@@ -444,6 +441,11 @@ export class GroupChatService {
444441
const connectionInfo = this.peerService.getConnectionInfo()
445442
const { peer } = this.get()
446443

444+
if (!peer) {
445+
console.error('Peer 不存在,无法处理连接')
446+
return
447+
}
448+
447449
// 创建新的群聊对象
448450
const newGroupChat: GroupChat = {
449451
id: roomId,
@@ -459,7 +461,7 @@ export class GroupChatService {
459461
isHost: false,
460462
shareLink: `${window.location.origin}${window.location.pathname}?roomId=${roomId}`,
461463
isLocalNetwork: isLocalNetwork,
462-
localIpAddress: connectionInfo.localIpAddress
464+
localIpAddress: connectionInfo.localIpAddress || undefined
463465
}
464466

465467
console.log('创建新的群聊对象:', newGroupChat)
@@ -486,7 +488,7 @@ export class GroupChatService {
486488
id: peer.id,
487489
name: userName,
488490
isLocalNetwork: isLocalNetwork,
489-
localIpAddress: connectionInfo.localIpAddress
491+
localIpAddress: connectionInfo.localIpAddress || undefined
490492
}
491493
})
492494

src/services/messageService.ts

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
import { nanoid } from 'nanoid'
22
import { EventEmitter } from '@/utils/eventEmitter'
33
import { Chat, GroupChat, Message } from '@/types/chat'
4-
5-
// 定义状态更新函数类型
6-
type SetFunction = (partial: Partial<any> | ((state: any) => Partial<any>)) => void
7-
type GetFunction = () => any
4+
import { ChatState, SetStateFunction, GetStateFunction } from '@/types/store'
85

96
export class MessageService {
107
constructor(
11-
private set: SetFunction,
12-
private get: GetFunction,
13-
private chatEvents: EventEmitter
8+
private set: SetStateFunction<ChatState>,
9+
private get: GetStateFunction<ChatState>,
10+
private readonly chatEvents: EventEmitter
1411
) { }
1512

1613
// 发送消息
@@ -48,7 +45,7 @@ export class MessageService {
4845
this.set({ currentChat: updatedChat })
4946

5047
// 更新聊天列表
51-
this.set((state: any) => ({
48+
this.set((state: ChatState) => ({
5249
chats: state.chats.map((chat: Chat) =>
5350
chat.id === currentChat.id ? updatedChat : chat
5451
)
@@ -61,7 +58,7 @@ export class MessageService {
6158
if (groupChat.isHost) {
6259
// 如果是主持人,发送给所有连接的成员
6360
const { connections } = this.get()
64-
Object.values(connections).forEach((conn: any) => {
61+
Object.values(connections).forEach((conn) => {
6562
try {
6663
conn.send({
6764
type: 'MESSAGE',
@@ -75,7 +72,7 @@ export class MessageService {
7572
} else {
7673
// 如果是成员,发送给主持人
7774
if (groupChat.connections && groupChat.connections.length > 0) {
78-
groupChat.connections.forEach((conn: any) => {
75+
groupChat.connections.forEach((conn) => {
7976
try {
8077
conn.send({
8178
type: 'MESSAGE',
@@ -101,7 +98,7 @@ export class MessageService {
10198
timestamp: new Date().toISOString()
10299
}
103100

104-
this.set((state: any) => ({
101+
this.set((state: ChatState) => ({
105102
messages: [...state.messages, systemMessage]
106103
}))
107104

src/services/peerService.ts

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
1-
import Peer from 'peerjs'
1+
import Peer, { DataConnection } from 'peerjs'
22
import { nanoid } from 'nanoid'
33
import { EventEmitter } from '@/utils/eventEmitter'
44
import { Chat, GroupChat, Message, User } from '@/types/chat'
5+
import { ChatState, SetStateFunction, GetStateFunction, PeerMessage } from '@/types/store'
56
import { cleanRoomId } from '@/utils/roomUtils'
67

7-
// 定义状态更新函数类型
8-
type SetFunction = (partial: Partial<any> | ((state: any) => Partial<any>)) => void
9-
type GetFunction = () => any
10-
118
export class PeerService {
129
private isLocalNetwork: boolean = false;
1310

1411
constructor(
15-
private set: SetFunction,
16-
private get: GetFunction,
12+
private set: SetStateFunction<ChatState>,
13+
private get: GetStateFunction<ChatState>,
1714
private chatEvents: EventEmitter
1815
) {
1916
// 检测是否在局域网环境
@@ -233,7 +230,7 @@ export class PeerService {
233230
console.log(`与 ${peerId} 的连接已打开`)
234231

235232
// 保存连接
236-
this.set((state: any) => ({
233+
this.set((state: ChatState) => ({
237234
connections: { ...state.connections, [peerId]: conn }
238235
}))
239236

@@ -249,7 +246,7 @@ export class PeerService {
249246
console.log('连接已关闭:', peerId)
250247

251248
// 从连接列表中移除
252-
this.set((state: any) => {
249+
this.set((state: ChatState) => {
253250
const newConnections = { ...state.connections }
254251
delete newConnections[peerId]
255252
return { connections: newConnections }
@@ -281,7 +278,7 @@ export class PeerService {
281278
}
282279

283280
// 处理接收到的数据
284-
handleReceivedData(data: any, peerId: string) {
281+
handleReceivedData(data: PeerMessage, peerId: string) {
285282
// 使用策略模式处理不同类型的消息
286283
const handlers: Record<string, (data: any, peerId: string) => void> = {
287284
'MESSAGE': this.handleMessageData.bind(this),
@@ -323,7 +320,7 @@ export class PeerService {
323320
id: data.id || nanoid()
324321
}
325322

326-
this.set((state: any) => ({ messages: [...state.messages, newMessage] }))
323+
this.set((state: ChatState) => ({ messages: [...state.messages, newMessage] }))
327324

328325
// 更新当前聊天的最后消息
329326
if (currentChat && (currentChat.id === data.roomId || !data.roomId)) {
@@ -336,7 +333,7 @@ export class PeerService {
336333
this.set({ currentChat: updatedChat })
337334

338335
// 更新聊天列表
339-
this.set((state: any) => ({
336+
this.set((state: ChatState) => ({
340337
chats: state.chats.map((chat: Chat) =>
341338
chat.id === currentChat.id ? updatedChat : chat
342339
)
@@ -348,7 +345,7 @@ export class PeerService {
348345
const { connections } = this.get()
349346

350347
// 转发给除了发送者之外的所有连接
351-
Object.entries(connections).forEach(([connPeerId, conn]: [string, any]) => {
348+
Object.entries(connections).forEach(([connPeerId, conn]: [string, DataConnection]) => {
352349
if (connPeerId !== peerId) {
353350
conn.send({
354351
type: 'MESSAGE',

src/store/useChatStore.ts

Lines changed: 3 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,15 @@
11
import { GroupChatService } from '@/services/groupChatService'
22
import { MessageService } from '@/services/messageService'
33
import { PeerService } from '@/services/peerService'
4-
import { Chat, GroupChat, Message } from '@/types/chat'
4+
import { GroupChat } from '@/types/chat'
5+
import { ChatState } from '@/types/store'
56
import { EventEmitter } from '@/utils/eventEmitter'
6-
import Peer from 'peerjs'
77
import { create } from 'zustand'
88

99
// 事件总线,用于跨组件通信
1010
export const chatEvents = new EventEmitter()
1111

12-
// 定义聊天状态接口
13-
interface ChatState {
14-
// 基础状态
15-
currentChat: Chat | null
16-
chats: Chat[]
17-
messages: Message[]
18-
loading: boolean
19-
isConnecting: boolean
20-
21-
// 用户信息
22-
userId: string
23-
userName: string | null
24-
25-
// PeerJS 相关
26-
peer: Peer | null
27-
connections: Record<string, any>
28-
isPeerInitialized: boolean
29-
pendingRoomId: string | null
30-
31-
// 网络模式
32-
isLocalNetwork: boolean
33-
localIpAddress: string | null
34-
35-
// 操作方法
36-
setCurrentChat: (chat: Chat | null) => void
37-
setUserName: (name: string) => void
38-
createGroupChat: () => void
39-
joinGroupChat: (roomId: string) => void
40-
sendMessage: (content: string) => void
41-
leaveCurrentChat: () => void
42-
copyShareLink: () => void
43-
setPendingRoomId: (roomId: string | null) => void
44-
toggleNetworkMode: () => boolean
45-
}
12+
// ChatState 接口已在 @/types/store 中定义
4613

4714
// 创建 Zustand store
4815
const useChatStore = create<ChatState>((set, get) => {

src/types/chat.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export interface GroupChat extends Chat {
4747
isHost: boolean
4848
shareLink?: string
4949
users: User[]
50-
connections?: any[]
50+
connections?: import('peerjs').DataConnection[]
5151
messages?: Message[]
5252
participants?: User[]
5353
isLocalNetwork?: boolean

src/types/store.ts

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import Peer, { DataConnection } from 'peerjs'
2+
import { Chat, Message, User } from './chat'
3+
4+
// 定义完整的聊天状态接口
5+
export interface ChatState {
6+
// 基础状态
7+
currentChat: Chat | null
8+
chats: Chat[]
9+
messages: Message[]
10+
loading: boolean
11+
isConnecting: boolean
12+
13+
// 用户信息
14+
userId: string
15+
userName: string | null
16+
17+
// PeerJS 相关
18+
peer: Peer | null
19+
connections: Record<string, DataConnection>
20+
isPeerInitialized: boolean
21+
pendingRoomId: string | null
22+
23+
// 网络模式
24+
isLocalNetwork: boolean
25+
localIpAddress: string | null
26+
27+
// 操作方法
28+
setCurrentChat: (chat: Chat | null) => void
29+
setUserName: (name: string) => void
30+
createGroupChat: () => void
31+
joinGroupChat: (roomId: string) => void
32+
sendMessage: (content: string) => void
33+
leaveCurrentChat: () => void
34+
copyShareLink: () => void
35+
setPendingRoomId: (roomId: string | null) => void
36+
toggleNetworkMode: () => boolean
37+
}
38+
39+
// 类型安全的状态更新函数
40+
export type SetStateFunction<T = ChatState> = (
41+
partial: Partial<T> | ((state: T) => Partial<T>)
42+
) => void
43+
44+
export type GetStateFunction<T = ChatState> = () => T
45+
46+
// PeerJS 消息类型定义
47+
export interface PeerMessage<T = any> {
48+
type: 'MESSAGE' | 'NEW_USER' | 'USER_JOINED' | 'ROOM_STATE' | 'USER_LEFT' | 'KEEP_ALIVE' | 'KEEP_ALIVE_ACK'
49+
data: T
50+
}
51+
52+
// 各种消息数据类型
53+
export interface MessageData extends Message {}
54+
55+
export interface NewUserData {
56+
id: string
57+
name: string
58+
isLocalNetwork?: boolean
59+
localIpAddress?: string
60+
}
61+
62+
export interface UserJoinedData extends NewUserData {}
63+
64+
export interface RoomStateData {
65+
users: User[]
66+
messages: Message[]
67+
}
68+
69+
export interface UserLeftData {
70+
id: string
71+
}
72+
73+
export interface KeepAliveData {
74+
timestamp: string
75+
}

0 commit comments

Comments
 (0)