import 'dart:convert'; import 'dart:developer'; import 'package:flutter/foundation.dart'; import 'package:mchess/api/websocket_message.dart'; import 'package:mchess/chess_bloc/chess_bloc.dart'; import 'package:mchess/chess_bloc/chess_events.dart'; import 'package:mchess/chess_bloc/chess_position.dart'; import 'package:mchess/api/register.dart'; import 'package:mchess/utils/chess_utils.dart'; import 'package:web_socket_channel/web_socket_channel.dart'; class ServerConnection { late WebSocketChannel channel; late bool wasConnected = false; late int counter = 0; Stream broadcast = const Stream.empty(); static final ServerConnection _instance = ServerConnection._internal(); ServerConnection._internal() { log("ServerConnection._internal constructor is called"); } factory ServerConnection() { return _instance; } factory ServerConnection.getInstance() { return ServerConnection(); } void send(String message) { channel.sink.add(message); counter++; } void connect(String playerID, lobbyID) { if (wasConnected) channel.sink.close(); if (kDebugMode) { channel = WebSocketChannel.connect(Uri.parse('ws://localhost:8080/api/ws')); } else { channel = WebSocketChannel.connect( Uri.parse('wss://chess.sw-gross.de:9999/api/ws')); } send(jsonEncode(WebsocketMessageIdentifyPlayer( playerID: (playerID), lobbyID: (lobbyID)))); log(channel.closeCode.toString()); wasConnected = true; broadcast = channel.stream.asBroadcastStream(); broadcast.listen(handleIncomingData); } void handleIncomingData(dynamic data) { log("Data received:"); log(data); var apiMessage = ApiWebsocketMessage.fromJson(jsonDecode(data)); switch (apiMessage.type) { case MessageType.colorDetermined: ChessBloc.getInstance().add(ColorDetermined( myColor: ChessColor.fromApiColor(apiMessage.color!))); break; case MessageType.moveMessage: handleIncomingMoveMessage(apiMessage); } } void handleIncomingMoveMessage(ApiWebsocketMessage apiMessage) { var move = ChessMove.fromApiMove(apiMessage.move!); if (move == ChessPosition.getInstance().lastMove) { //This is our own move that got resent by the server. Do not process. } else { log('lastMove: from: ${ChessPosition.getInstance().lastMove?.from} to: ${ChessPosition.getInstance().lastMove?.to}'); log('constructed move: from: ${move.from} to: ${move.to}'); log('Move received : ${move.from.toAlphabetical()}->${move.to.toAlphabetical()}'); ChessBloc.getInstance() .add(OpponentPieceMoved(startSquare: move.from, endSquare: move.to)); } } }