// CONCURRENCIA rebre i enviar // Aquests dos métodes utilitzen recursos compartits, els buffers d'enviament // i recepció, per tant els synchronitzem. public synchronized void rebre(SelectionKey clau) throws IOException { SocketChannel s = ((SocketChannel) clau.channel()); int userId = arraySocketChannels.indexOf(s); bbReceptor.clear(); s.read(bbReceptor); bbReceptor.flip(); // Comprovem que hagi rebut un Integer if (bbReceptor.remaining() == 4) controlador.keyPressed(bbReceptor.getInt(), userId); }
@Override public void update(Observable o, Object arg) { // ENVIAR POSICIONS // Si el que volem és actualitzar les posicions al joc if (arg instanceof int[]) { int[] lastPosition = (int[]) arg; enviar(lastPosition); } // ACABAR PARTIDA // Si el que volem és acabar la partida else if (arg instanceof Integer) { if ((int) arg == Const.ACABA_PARTIDA) { System.out.println( "~Partida Acabada | Desconectem " + arraySocketChannels.size() + " jugadors"); controlador.acaba(); enviar(Const.FINISH_CODE); System.out.print("Cancelació de les Claus..."); // CONCURRENCIA claus // Les claus son recursos compartits. Un dels problemes que ens podem trobar, // es que abans de que els clients rebin el FINISH_CODE, enviïn un paquet, // i quan es procesi la clau sigui cancelada. // CANCELEM LES CLAUS // Hem de cancelar només les claus que pertanyen a conexions amb // clients, que son les que retornen un SocketChannel quan invoquem // key.channel() synchronized (this) { for (SelectionKey key : selector.keys()) { if (key.channel() instanceof SocketChannel && arraySocketChannels.contains((SocketChannel) key.channel())) { key.cancel(); System.out.print(" | Clau cancelada"); } } } arraySocketChannels.clear(); System.out.println("\nArray de SocketChannels 'cleared'"); } } }
public void ferAccept(SelectionKey clau) throws IOException { SocketChannel s = ((ServerSocketChannel) clau.channel()).accept(); s.configureBlocking(false); s.register(selector, SelectionKey.OP_READ); arraySocketChannels.add(s); System.out.println("Conexió Acceptada | " + arraySocketChannels.size() + " jugadors conectats"); // INICI DEL JOC // Inicia el Joc quan es conecta el 2n Jugador if (arraySocketChannels.size() > 1) { System.out.println("~Comença el Joc!~"); controlador.inici(); // Fem Broadcast de les millors puntuacions int[] score = model.getBestScore(); enviar(new int[] {Const.ENVIA_PUNTIACIONS, Const.ENVIA_PUNTIACIONS, score[0], score[1]}); } }