2022年11月27日 星期日

用 dart 語言寫簡單的 SocketServer 聊天室

// server.dart
import 'dart:io';
import 'dart:convert';
class ChatRoom {
  int key = 0;
  static int sn = 0;
  static Map<int, Socket> sockets = { };
  void broadcast(List<int> data) {
    sockets.forEach((id, session) {
      if (key != id) session.add(utf8.encode('id$key:>${utf8.decode(data)}'));
    });
  }
  void relay(List<int> data) async {
    String text = utf8.decode(data).trim();
    if (text == 'quit') {
      print('relay: $text');
      final session = sockets.remove(key);
      await session?.close();
    }
    broadcast(data);
  }
  void shutdown( ) {
    sockets.remove(key);
    broadcast(utf8.encode('bye!\n'));
    print('id$key leave, remain ${sockets.length}');  
  }
  ChatRoom (Socket session) {
    key = ++sn;
    session .. add(utf8.encode('id${key} welcome!\n')) .. listen(
      relay,
      onDone: shutdown,
      onError: (_) => session.close()
    );
    sockets[key] = session;
    print('id$key join [total ${sockets.length}]');
  }
}
void main( ) {
  int port = 8080;
  print("Chat room at $port");
  ServerSocket.bind(InternetAddress.anyIPv4, port).then((ServerSocket server) {
    server.listen((socket) => ChatRoom(socket));    
  });
}
使用 dart VM 來跑: dart server.dart, 之後就可以用  telnet 127.0.0.1  8080 讓客戶端連進聊天室, 只是 linux 上的 telnet client 在中文編/解碼上, 雖然接收時解中文碼沒問題, 但傳送時編成的中文碼可能會有問題, 幸好用 dart 語言編寫相同功能的 telnet 終端機不是難事:
// client.dart
import 'dart:io';
import 'dart:convert';
void main(List<String>  args)  async {
      String ip = (args.length  >  0) ?  args[0]  :  'localhost';
      int port  = (args.length  >  1)  ?  int.parse(args[1])  :  8080;
      Socket  session = await  Socket.connect(ip,  port);
      session.listen (
           (dynamic data) => print((data is String) ? data  : utf8.decode(data).trim()),
           onDone: (  )  =>  exit(0),
           onError: (_)  =>  session.close()
      );
      stdin.listen (
         (List<int> data) {
              try {//  print(data);
                if  (utf8.decode(data).trim() == 'quit')  throw 'user quit';
                else  session.add(data);
             } catch(e) {
               print('stdin: $e, $data');
               session.close();
               exit(0);
            }
         }
     );
}
同樣用 dart VM 來跑: dart client.dart

沒有留言:

張貼留言

使用 pcie 轉接器連接 nvme SSD

之前 AM4 主機板使用 pcie ssd, 但主機板故障了沒辦法上網, 只好翻出以前買的 FM2 舊主機板, 想辦法讓老主機復活, 但舊主機板沒有 nvme 的界面, 因此上網買了 pcie 轉接器用來連接 nvme ssd, 遺憾的是 grub2 bootloader 無法識...