0

I've implemented a global chat that communicates through sockets. A client writes a message that is send to the server and than the server sends the message back to all clients. Each client it's represented by a class called ClientThread, so each client it's a thread. Each time a new client connects I create a new ClientThread instance and store all those instances inside a list. Now I want to implement a private chat, so each client can talk with another client in private (or a group chat where are 2,3 or more).

Now my question is how can I do this. I mean I was thinking that whenever a client wants to start a private conversation with another client, send this request to the server, and the server will store those two instances of ClientThread in a list, and will be the only one who will recieve those messages.

First question is how can I store those conversations. What is best to use? Taking into consideration the fact that in a private conversation can be one, two or more clients and a client can have multiple private conversations, I want to be able to easily recognize where the message comes from and where to send it back.

I also want to say the fact that I only communicate through instances of ChatMessage class, a class that i defined my self and it has a type field and a message field. So whenever a user sends a private message to another user, the server will receive that message with type PRIVATEMESSAGE, iterate through all the list with conversations that are stored and send the message to the particular conversation that send that request.

//output and input stream
    output = new ObjectOutputStream(socket.getOutputStream());
    input = new ObjectInputStream(socket.getInputStream());

// send messages
    public void sendMessage(Object msg) {
            try {
                
                output.writeObject(msg);
            } catch (IOException e) {
                e.printStackTrace();
            }
    }


public class ChatMessage implements Serializable {

    protected static final long serialVersionUID = 1112122200L;

    // The different types of message sent by the Client
    // WHOISIN to receive the list of the users connected
    // MESSAGE an ordinary message
    // LOGOUT to disconnect from the Server
    public static final int WHOISIN = 0;

    public static final int MESSAGE = 1;

    public static final int LOGOUT = 2;

    public static final int LOGIN = 3;
    
    public static final int PRIVATECONVERSATION = 4;
    
    public static final int PRIVATEMESSAGE = 5;
    
    private int type;
    private String message;

    // constructor
    public ChatMessage(int type, String message) {
        this.type = type;
        this.message = message;
    }

    // getters
    public int getType() {
        return type;
    }

    public String getMessage() {
        return message;
    }
}
 

And now comes my second question:

Is there a way I cand send files through this ChatMessage class? I mean maybe i can have a separate field and whenever I get type FILE for example, I read bytes from that field? Is this possible?

Community
  • 1
  • 1
Alex Chihaia
  • 103
  • 2
  • 15
  • 1
    I would recommend implementing the concept of Rooms, i.e. each room is an instance of a conversation with multiple members. Take a look at something called SmartFoxServer - it's a tool that could handle this and takes Java extensions with custom code. Might not be suitable/overkill for what you're looking for, but worth a comment! – Shakespeare Apr 12 '16 at 18:28

2 Answers2

0

I also coded a simple chatting program and i made a "user" class with a list of messages as a field. Every message is an object with "from", "to" etc and the text. The message list can be iterated separated for every User

m4dcheese
  • 1
  • 1
0

for your first question take a look at this you could create a similiar table as specified here Database Design for storing Chat Messages between people

To send files you could convert them to bytes and send them as follows:-

public byte[] read() throws IOException
{
    int length = inputStream.readInt();
    byte[] dataBytes = new byte[length];
    inputStream.readFully(dataBytes, 0, dataBytes.length);
    return dataBytes;
}

public void write(byte[] data, Short packetType) throws IOException
{
    outputStream.writeShort(packetType);
    outputStream.writeInt(data.length);
    outputStream.write(data);
    outputStream.flush();
}

To convert files to bytes :-

Path path= Paths.get("file/path");
byte[] data = Files.readAllBytes(path);

To convert bytes back to file :-

byte[] data = read();
Path path = Paths.get("C:\myfile.FileType");
Files.write(path, bytes);

Send the file name along with its extension then send the file that way you can recreate it back on the other end.

  • The thing is that I only communicate through ChatMessage instances. Is there a way I can store those bytes inside a ChatMessage instance? – Alex Chihaia Apr 14 '16 at 00:17
  • @AlexChihaia you could make an array list of bytes and keep the file byte array as an element of the array list, but usually you would want to save files somewhere on the local hard drive, you could create a temporary file or set these files as deleteOnExit() so that they are deleted when your program exits –  Apr 14 '16 at 15:28