WebSocket

Finch 通过三类设计支持 WebSocket:SocketManager 用于注册,SocketEvent 用于定义事件,SocketController 用于处理消息。

设置

1. 创建 SocketController

import 'package:finch/finch_route.dart';

class ChatController extends SocketController {
  @override
  void onConnect(SocketClient client) {
    print('用户已连接:\${client.id}');
    sendToAll(SocketEvent('user_joined', {'id': client.id}));
  }

  @override
  void onDisconnect(SocketClient client) {
    sendToAll(SocketEvent('user_left', {'id': client.id}));
  }

  @override
  void onMessage(SocketClient client, SocketEvent event) {
    switch (event.name) {
      case 'chat_message':
        var message = event.data['message'] as String;
        sendToAllExcept(
          client,
          SocketEvent('chat_message', {
            'from': client.id,
            'message': message,
          }),
        );
        break;
    }
  }
}

2. 注册 WebSocket 路由

router.ws('/chat', ChatController());

SocketController 方法

方法 描述
sendTo(client, event) 发送给指定客户端
sendToAll(event) 发送给所有已连接的客户端
sendToAllExcept(client, event) 发送给除某客户端之外的所有人
broadcast(room, event) 发送到一个房间
joinRoom(client, room) 将客户端加入房间
leaveRoom(client, room) 将客户端移出房间

JavaScript 客户端

const socket = new WebSocket('ws://localhost:8080/chat');

socket.onopen = () => {
  console.log('已连接');
};

socket.onmessage = (event) => {
  const data = JSON.parse(event.data);
  console.log('收到事件:', data.name, data.data);
};

function sendMessage(message) {
  socket.send(JSON.stringify({
    name: 'chat_message',
    data: { message }
  }));
}

socket.onclose = () => {
  console.log('连接已断开');
};

房间(Rooms)

@override
void onMessage(SocketClient client, SocketEvent event) {
  if (event.name == 'join_room') {
    var room = event.data['room'] as String;
    joinRoom(client, room);
    broadcast(room, SocketEvent('room_joined', {'user': client.id}));
  }
}