You are on page 1of 16

Chat Multicast

Aplicaciones para comunicaciones en RED

3CM16
Luis Diego Jiménez Delgado
10 de octubre de 2021

Luis Diego Jiménez Delgado 1

El chat multicast funciona generando un cliente de chat que en el background


ejecuta un hilo que manda y escucha todos los mensajes del socket multidifusión,
discrimina los mensajes que no le pertenecen y agrega los mensajes que son
públicos o que van dirigidos hacia el.

Luis Diego Jiménez Delgado 2

Luis Diego Jiménez Delgado 3


package practica4;

/**
*
* @author luis
*/
public interface IView {

void loadView();

void loadContent();

void loadActions();
}

package practica4;

/**
*
* @author luis
*/
public interface ContactListCallback {

public void onContactSelected(String contact);

public void onContactUnselect();

package practica4;

/**
*
* @author luis
*/
public interface MulticastCallback {

public void send(boolean isCorrect);

public void newContact(String contact);

public void killContact(String contact);

public void privateMessage(String message, String from);

public void publicMessage(String message, String from);


}

package practica4;

Luis Diego Jiménez Delgado 4

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.border.MatteBorder;

/**
*
* @author luis
*/
public class ContactListView extends JPanel implements IView {

public String userName;


private final Map<String, JPanel> contacts;
private JPanel mainList;
private final ContactListCallback callback;
private String selectedContact;

public ContactListView(String userName, ContactListCallback callback) {


this.userName = userName;
this.callback = callback;
contacts = new HashMap<>();
}

public void start() {


loadView();
loadContent();
loadActions();
this.invalidate();
this.validate();
this.repaint();
}

@Override
public void loadView() {
setLayout(new BorderLayout());
mainList = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.weightx = 1;
gbc.weighty = 1;
mainList.add(new JPanel(), gbc);
add(new JScrollPane(mainList));
}

@Override
public void loadContent() {

@Override

Luis Diego Jiménez Delgado 5

public void loadActions() {

public void addContact(String contact) {


if (!contacts.containsKey(contact)) {
createContactPanel(contact);
mainList.invalidate();
mainList.validate();
mainList.repaint();
this.invalidate();
this.validate();
this.repaint();

}
}

public void deleteContact(String contact) {


if (contacts.containsKey(contact)) {
JPanel panel = contacts.remove(contact);
mainList.remove(panel);
mainList.invalidate();
mainList.validate();
mainList.repaint();
}
}

private JPanel createContactPanel(String contact) {


JPanel panel = new JPanel();
panel.add(new JLabel(contact));
panel.setBorder(new MatteBorder(0, 0, 1, 0, Color.GRAY));
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.weightx = 100;
gbc.fill = GridBagConstraints.HORIZONTAL;
panel.setBackground(Color.WHITE);
contacts.put(contact, panel);
mainList.add(panel, gbc, 0);
panel.addMouseListener(new MouseListener() {
@Override
public void mouseClicked(MouseEvent e) {
if (selectedContact != null) {
JPanel helper = contacts.get(selectedContact);
helper.setBackground(Color.WHITE);
callback.onContactUnselect();
}
if (!contact.equals(selectedContact)) {
selectedContact = contact;
panel.setBackground(Color.CYAN);
callback.onContactSelected(contact);
}

@Override
public void mousePressed(MouseEvent e) {
}

Luis Diego Jiménez Delgado 6

@Override
public void mouseReleased(MouseEvent e) {
}

@Override
public void mouseEntered(MouseEvent e) {
}

@Override
public void mouseExited(MouseEvent e) {
}
});
return panel;
}

/*
* To change this license header, choose License Headers in Project
Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package practica4;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.border.MatteBorder;

/**
*
* @author luis
*/
public class MessageListView extends JPanel implements IView {

public String userName;


private JPanel mainList;

public MessageListView(String userName) {


this.userName = userName;

public void start() {


loadView();
loadContent();
loadActions();
this.invalidate();
this.validate();
this.repaint();
}

@Override

Luis Diego Jiménez Delgado 7

public void loadView() {


setLayout(new BorderLayout());
mainList = new JPanel(new GridBagLayout());
mainList.setBackground(Color.WHITE);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.weightx = 1;
gbc.weighty = 1;
mainList.add(new JPanel(), gbc);
add(new JScrollPane(mainList));
}

@Override
public void loadContent() {

@Override
public void loadActions() {

public String parseMessage(String message) {


String result = message;
result = result.replace(":)", "<img src='https://voz-del-
caribe.s3.amazonaws.com/pruebas/risa.png' width=\"100\" height=\"100\"></
img>");
result = result.replace(":o", "<img src='https://voz-del-
caribe.s3.amazonaws.com/pruebas/amor.png' width=\"100\" height=\"100\"></
img>");
result = result.replace(":S", "<img src='https://voz-del-
caribe.s3.amazonaws.com/pruebas/enojo.png' width=\"100\" height=\"100\"></
img>");
result = result.replace("_loco_", "<img src='https://voz-del-
caribe.s3.amazonaws.com/pruebas/loco.gif' width=\"100\" height=\"100\"></
img>");
result = result.replace("_Homero_", "<img src='http://
tusimagenesde.com/wp-content/uploads/2015/01/gifs-animados-5.gif'
width=\"100\" height=\"100\"></img>");
return result;
}

public void privateMessage(String message, String from) {


if (message != null && !message.equals("")) {
String content = "<html>"
+ "<b> Privado de: " + from + " </b> <br/>"
+ parseMessage(message)
+ "</html>";
createPanel(content);
}
}

public void publicMessage(String message, String from) {


if (message != null && !message.equals("")) {
String content = "<html>"
+ "<b> Publico de: " + from + " </b> <br/>"
+ parseMessage(message)
+ "</html>";

Luis Diego Jiménez Delgado 8

createPanel(content);
}
}

public void addPublicMessage(String message) {


System.out.println("addPublicMessage");
if (message != null && !message.equals("")) {
System.out.println("aaaaa");
String content = "<html>"
+ "<b> Enviaste a todos: " + " </b> <br/>"
+ parseMessage(message)
+ "</html>";
createPanel(content);
}
}

public void addPrivateMessage(String message, String from) {


System.out.println("gola");
if (message != null && !message.equals("")) {
String content = "<html>"
+ "<b> Enviaste a " + from + ": " + " </b> <br/>"
+ parseMessage(message)
+ "</html>";
createPanel(content);
}
}

private JPanel createPanel(String message) {


JPanel panel = new JPanel();
panel.add(new JLabel(message));
panel.setBorder(new MatteBorder(0, 0, 1, 0, Color.GRAY));
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.weightx = 100;
gbc.fill = GridBagConstraints.HORIZONTAL;
mainList.add(panel, gbc, 0);
this.invalidate();
this.validate();
this.repaint();
return panel;
}

}
package practica4;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.util.HashMap;
import java.util.Map;

/*
* To change this license header, choose License Headers in Project
Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.

Luis Diego Jiménez Delgado 9

*/
/**
*
* @author luis
*/
public class MulticastClient {

public static MulticastSocket socket;


public static InetAddress addr;
public static final int PORT = 4000;
public MulticastCallback callback;
public String userName;

public MulticastClient(MulticastCallback callback, String userName) {


this.callback = callback;
this.userName = userName;
}

public void start() {


try {
socket = new MulticastSocket(PORT);
socket.setReuseAddress(true);
socket.setTimeToLive(1);
addr = InetAddress.getByName("230.1.1.1");
socket.joinGroup(addr);
Thread threadListener = new Thread(new Listener(callback));
threadListener.start();
} catch (IOException e) {
System.out.println(e);
}
}

public void sendPrivateMessage(String message, String receiver) {


Thread threadSender = new Thread(new Sender("<privado><" + userName +
"><" + receiver + ">" + message, callback));
threadSender.start();
}

public void sendMessage(String message) {


Thread threadSender = new Thread(new Sender("<msj><" + userName + ">"
+ message, callback));
threadSender.start();
}

public void sendWelcomeMessage() {

Thread threadSender = new Thread(new Sender("<inicio>" + userName,


callback));
threadSender.start();

public void sendGoodbye() {


Thread threadSender = new Thread(new Sender("<fin>" + userName,
callback));
threadSender.start();
}

Luis Diego Jiménez Delgado 10

class Sender implements Runnable {

public String message;


public MulticastCallback callback;

public Sender(String message, MulticastCallback callback) {


super();
this.message = message;
this.callback = callback;
}

@Override
public void run() {
byte[] b = message.getBytes();
DatagramPacket packet = new DatagramPacket(b, b.length, addr,
PORT);
try {
socket.send(packet);
System.out.println("Enviando mensaje: '" + message + "' con
un TTL: " + socket.getTimeToLive());
callback.send(true);
} catch (IOException ex) {
System.out.println(ex);
}
}
}

class Listener implements Runnable {

public MulticastCallback callback;

public Map<String, String> contacts = new HashMap<>();

public Listener(MulticastCallback callback) {


super();
this.callback = callback;
}

public void addContact(String contact) {


if (!contacts.containsKey(contact) && !contact.equals(userName))
{
contacts.put(contact, "");
callback.newContact(contact);
}
}

public void deleteContact(String contact) {


if (contacts.containsKey(contact) && !contact.equals(userName)) {
contacts.remove(contact);
callback.killContact(contact);
}
}

public void privateMessage(String message) {


String tag = "<" + userName + ">";
if (message.contains(tag)) {
message = message.replace(tag, "");
String sender = extractSender(message);

Luis Diego Jiménez Delgado 11

if (!sender.equals("") && !sender.equals(userName)) {


message = message.replace("<" + sender + ">", "");
addContact(sender);
System.out.println(message.length());
System.out.println("privado:" + message + "ss");
callback.privateMessage(message, sender);
}

}
}

public void publicMessage(String message) {


String sender = extractSender(message);
addContact(sender);
if (!sender.equals(userName)) {
callback.publicMessage(message, sender);
}
}

private String extractSender(String message) {


try {
message = message.substring(1);
int index = message.indexOf(">");
if (index >= 0) {
return message.substring(0, index);
}
return "";
} catch (Exception ex) {
return "";
}
}

public void actionSelector(String message) {


if (message != null) {
if (message.startsWith("<inicio>")) {
message = message.replace("<inicio>", "");
addContact(message);
return;
}
if (message.startsWith("<fin>")) {
message = message.replace("<fin>", "");
deleteContact(message);
return;
}
if (message.startsWith("<privado>")) {
message = message.replace("<privado>", "");
privateMessage(message);
return;
}
if (message.startsWith("<msj>")) {
message = message.replace("<msj>", "");
publicMessage(message);
}
}
}

@Override
public void run() {

Luis Diego Jiménez Delgado 12

System.out.println("cliente iniciado");
while (true) {
DatagramPacket packet = new DatagramPacket(new byte[512],
512);
try {
socket.receive(packet);
String received = new String(packet.getData());
String response = "";
for (int i = 0; i < received.length(); ++i) {
if ((received.charAt(i) >= 'a' && received.charAt(i)
<= 'z')
|| (received.charAt(i) >= 'A' &&
received.charAt(i) <= 'Z')
|| (received.charAt(i) >= '0' &&
received.charAt(i) <= '9')
|| received.charAt(i) == ' '
|| received.charAt(i) == '.'
|| received.charAt(i) == ','
|| received.charAt(i) == '<'
|| received.charAt(i) == '>'
|| received.charAt(i) == '_'
|| received.charAt(i) == '-'
|| received.charAt(i) == ':') {
response += received.charAt(i);
}
}
actionSelector(response);
} catch (IOException ex) {
System.out.println(ex);
}
}
}

}
}

/*
* To change this license header, choose License Headers in Project
Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package practica4;

import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;

/**
*
* @author luis
*/
public class MainView extends JFrame implements IView {

Luis Diego Jiménez Delgado 13

public ContactListView contactList;


public MessageListView messageList;
public String userName;
public MulticastClient client;
public JTextField text;
public JLabel label;
public JButton button;
public String selectedContact;

public MainView(String userName) {


this.userName = userName;
}

public void start() {


loadView();
loadActions();
loadContent();
this.invalidate();
this.validate();
this.repaint();
}

@Override
public void loadView() {
setLayout(null);
setSize(750, 550);
setVisible(true);
text = new JTextField();
text.setBounds(250, 420, 450, 80);
text.setVisible(true);
label = new JLabel("Enviar mensaje para todos:");
label.setBounds(250, 400, 500, 20);
label.setVisible(true);

button = new JButton("Enviar");


button.setBounds(700, 420, 50, 50);
button.setVisible(true);

this.setDefaultCloseOperation(EXIT_ON_CLOSE);
contactList = new ContactListView(this.userName, new
ContactListCallback() {
@Override
public void onContactSelected(String contact) {
selectedContact = contact;
label.setText("Enviar mensaje para " + contact + ":");
}

@Override
public void onContactUnselect() {
selectedContact = null;
label.setText("Enviar mensaje para todos:");
}
});
contactList.setBounds(0, 0, 250, 500);
contactList.start();
contactList.setVisible(true);
messageList = new MessageListView(this.userName);

Luis Diego Jiménez Delgado 14

messageList.setBounds(250, 0, 500, 400);


messageList.start();
messageList.setVisible(true);

this.add(contactList);
this.add(messageList);
this.add(text);
this.add(label);
this.add(button);

@Override
public void loadContent() {

@Override
public void loadActions() {
client = new MulticastClient(new MulticastCallback() {
@Override
public void send(boolean isCorrect) {
System.err.println(isCorrect ? "el mensaje se envio
correctamente" : "el mensaje es incorrecto");
}

@Override
public void newContact(String contact) {
contactList.addContact(contact);
client.sendPrivateMessage("", contact);
}

@Override
public void killContact(String contact) {
contactList.deleteContact(contact);
}

@Override
public void privateMessage(String message, String from) {
messageList.privateMessage(message, from);
}

@Override
public void publicMessage(String message, String from) {
messageList.publicMessage(message, from);
}

}, userName);
client.start();
client.sendWelcomeMessage();
button.addActionListener((ActionEvent e) -> {
String message = text.getText();
if (message != null && !message.equals("")) {
if (selectedContact != null) {
client.sendPrivateMessage(message, selectedContact);
messageList.addPrivateMessage(message, selectedContact);
} else {
client.sendMessage(message);

Luis Diego Jiménez Delgado 15

messageList.addPublicMessage(message);
}
text.setText("");
}
});
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
client.sendGoodbye();
System.exit(0);
}
});
}

package practica4;

/**
*
* @author luis
*/
public class Practica4 {

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
MainView mainView = new MainView("usurariofinal");
mainView.start();
}

Luis Diego Jiménez Delgado 16

You might also like