Java curriculum design - personal summary

Java curriculum design - personal summary

Java curriculum design team -socket chat room (Day4 summary article)

Modules personal responsibility and mission statement

  1. transmitted to the user terminal server code

  2. user terminal receives the code sent by the server

  3. Storing a data structure recorded message

  4. Participate in server-side code written

  5. Responsible for the entire system of receiving and forwarding logic specific logic

Gitee commit record

Part of the commit record

The impact of the various branches of the master branch

Submit detailed personal record

The mandate detail

I will forward the information is divided into three cases:

1. When the user logs off-line system immediately after the user transmits others offline message sent to him

class OfflineMessage

2. When users send someone to his online news online

class OnlineMessage

3. Historical information requested by the user to the server

class HistoryMessage

Because the members are the same, so they inherited from class Message, specifically with regard to the following parties UML class diagram shows

Now use the socket to send, then we need implements Serializable, so serialization

Client specific transmission - reception Model

Attached is a UML class diagram

Which method and members of the class UserController

public class UserController 

In this class used to send a variety of information, such as login request, the registration request, the history information request, send messages, send files

Login request:
public static void requestLogin(User user) throws IOException {
    objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
    objectOutputStream.writeObject(user);
    objectOutputStream.flush();

}

Send obtain from the GUI to the User object

Registration Request:
public static void requestRegister(UserInformation userInformation) throws IOException {
    objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
    objectOutputStream.writeObject(userInformation);
    objectOutputStream.flush();

}

Send obtain registration information from the GUI to the object UserInformation

History message requests:
public static void requestHistoryMessage() throws IOException {

    objectOutputStream.writeObject(new HistoryMessage(null,null,null,null));
    objectOutputStream.flush();

}

Send a HistoryMessage object requests the server to return all the historical information about the user

Send a message to each other:
public static void sendMessage(OnlineMessage onlineMessage) throws IOException {

    objectOutputStream.writeObject(onlineMessage);
    objectOutputStream.flush();

}

The GUI acquired OnlineMessage objects to the server, the server to determine whether to forward

Send files to other objects:
public static void sendDocument(UserDocument userDocument) throws IOException {
    objectOutputStream.writeObject(new UserDocument(null,null,null));
    objectOutputStream.writeObject(userDocument);
    objectOutputStream.flush();

}

public static UserDocument getUserDocumentByPath(String receiver, String filePath,String fileName) throws IOException {
    File file = new File(filePath);
    DataInputStream dataInputStream = new DataInputStream(new FileInputStream(filePath));
    byte[] buf = new byte[1024 * 9];
    dataInputStream.read(buf);
    UserDocument userDocument=new UserDocument(receiver,buf,fileName);
    return userDocument;
}

The user needs to send the information loaded into byte array, and then loaded into UserDocument object sent to the server

inherited from class ReceiveThread Thread, for continuously detecting the service end message sent, which is continuously detected in the run method

public void run() {
        while(true){
            try {
                Object object = objectInputStream.readObject();
                if(object.equals("Find error in user regist!")){
                    //注册失败
                    RegisteJFrame.registrationReturnInformation("Find error in user regist!");
                }else if(object.equals("user created successfully!")){
                    //注册成功
                    RegisteJFrame.registrationReturnInformation("user created successfully!");
                }else if(object.equals("Login successful!")){
                    Login.changePermission(2);
                    //登陆成功
                }else if(object.equals("Login error!")){
                    Login.changePermission(1);
                }else if(object.getClass().toString().equals("class user.User")){
                    //返回数据库中列表信息cxxx
                    User tempUser;
                    ArrayList<User> personList = new ArrayList<>();
                    while(true){
                        tempUser = (User) objectInputStream.readObject();
                        if(tempUser.getUserName()==null) break;
                        personList.add(tempUser);
                    }
                    ContactJFrame.returnListInformation(personList);
                    ContactJFrame.setButton();

                }else if(object.getClass().toString().equals("class message.OfflineMessage")){

                     Message tempMessage;
                    ArrayList<OfflineMessage> offlineMessageArrayList = new ArrayList<>();
                    while(true){
                        tempMessage = (Message)objectInputStream.readObject();
                        if(tempMessage.getSender()==null) break;
                        OfflineMessage tempOfflineMessage = (OfflineMessage)tempMessage;
                        offlineMessageArrayList.add(tempOfflineMessage);
                        ContactJFrame.changeButton(tempMessage);
                    }
                    if(offlineMessageArrayList.size()!=0){
                        File file = new File("信息提示.mp3");
                        FileInputStream fileInputStream = new FileInputStream(file);
                        BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
                        Player player = new Player(bufferedInputStream);
                        player.play();
                    }
                    ContactJFrame.returnOfflineMessage(offlineMessageArrayList);

                }else if(object.getClass().toString().equals("class message.OnlineMessage")){
                    OnlineMessage onlineMessage = (OnlineMessage)objectInputStream.readObject();
                    File file = new File("信息提示.mp3");
                    FileInputStream fileInputStream = new FileInputStream(file);
                    BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
                    Player player = new Player(bufferedInputStream);

                    player.play();
                    ContactJFrame.returnOnlineMessage(onlineMessage);

                }else if(object.getClass().toString().equals("class message.HistoryMessage")){
                    Object o;
                    ArrayList<HistoryMessage> historyMessageArrayList = new ArrayList<>();
                    while(true){
                        o = objectInputStream.readObject();
                        HistoryMessage t = (HistoryMessage)o;
                        if(t.getSender()==null) break;
                        historyMessageArrayList.add(t);
                    }
                    ContactJFrame.returnHistoryList(historyMessageArrayList);

                }
                else if(object.getClass().toString().equals("class user.UserDocument"))
                {
                    Object o=objectInputStream.readObject();
                    UserDocument userDocument=(UserDocument) o;

                    ContactJFrame.receiveUserDocument(userDocument);
                }
            } catch (IOException | ClassNotFoundException | JavaLayerException e) {
                JOptionPane.showMessageDialog(null,"连接已断开,请重新登录!");
                return;
            }
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }

Because if - else statement is a bit much, so I will explain one by one

if(object.equals("Find error in user regist!")){
                    //注册失败
                    RegisteJFrame.registrationReturnInformation("Find error in user regist!");
                }

This server is used to determine whether to return not allowed to register, registration will be allowed to create a new dialog box returns a registration error

else if(object.equals("user created successfully!")){
    //注册成功
    RegisteJFrame.registrationReturnInformation("user created successfully!");
}

Registration is successful, a new dialog box that shows successful registration!

else if(object.equals("Login successful!")){
    Login.changePermission(2);
    //登陆成功
}

Successful login, create a chat window

else if(object.equals("Login error!")){
    Login.changePermission(1);
}

Login failed, to create a dialog box that shows your password or account error

else if(object.getClass().toString().equals("class user.User")){
    //返回数据库中列表信息cxxx
    User tempUser;
    ArrayList<User> personList = new ArrayList<>();
    while(true){
        tempUser = (User) objectInputStream.readObject();
        if(tempUser.getUserName()==null) break;
        personList.add(tempUser);
    }
    ContactJFrame.returnListInformation(personList);
    ContactJFrame.setButton();

}

假如检测到有User对象传进来,那么就认为已经成功登录,正在返回所有人的列表,创建所有人的Button

else if(object.getClass().toString().equals("class message.OfflineMessage")){

    Message tempMessage;
    ArrayList<OfflineMessage> offlineMessageArrayList = new ArrayList<>();
    while(true){
        tempMessage = (Message)objectInputStream.readObject();
        if(tempMessage.getSender()==null) break;
        OfflineMessage tempOfflineMessage = (OfflineMessage)tempMessage;
        offlineMessageArrayList.add(tempOfflineMessage);
        ContactJFrame.changeButton(tempMessage);
    }
    if(offlineMessageArrayList.size()!=0){
        File file = new File("信息提示.mp3");
        FileInputStream fileInputStream = new FileInputStream(file);
        BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
        Player player = new Player(bufferedInputStream);
        player.play();
    }
    ContactJFrame.returnOfflineMessage(offlineMessageArrayList);

}

成功返回所有人列表之后,检测是否有离线消息发过来,如果有的话将会响起提示音,并将发送离线消息的人对应的Button变红,如果鼠标已经点击了那个Button,那么将离线消息直接输出到对话框

else if(object.getClass().toString().equals("class message.OnlineMessage")){
    OnlineMessage onlineMessage = (OnlineMessage)objectInputStream.readObject();
    File file = new File("信息提示.mp3");
    FileInputStream fileInputStream = new FileInputStream(file);
    BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
    Player player = new Player(bufferedInputStream);

    player.play();
    ContactJFrame.returnOnlineMessage(onlineMessage);

}

检测是否有人在线的情况下发送信息,如果有在线消息的话,响起提示音,并将对应那个人的Button变红,如果Button处于点击状态,那么将消息直接输出到对话框

else if(object.getClass().toString().equals("class message.HistoryMessage")){
    Object o;
    ArrayList<HistoryMessage> historyMessageArrayList = new ArrayList<>();
    while(true){
        o = objectInputStream.readObject();
        HistoryMessage t = (HistoryMessage)o;
        if(t.getSender()==null) break;
        historyMessageArrayList.add(t);
    }
    ContactJFrame.returnHistoryList(historyMessageArrayList);

}

检测服务器是否将历史消息发送过来,持续将历史消息的列表接收完成,将历史消息存入数据结构中,判断机制在后面会讲

else if(object.getClass().toString().equals("class user.UserDocument")) {
    Object o=objectInputStream.readObject();
    UserDocument userDocument=(UserDocument) o;

    ContactJFrame.receiveUserDocument(userDocument);
}

检测是否有文件发送过来,如果有的话接收,然后返回给GUI询问是否保存文件

 catch (IOException | ClassNotFoundException | JavaLayerException e) {
    JOptionPane.showMessageDialog(null,"连接已断开,请重新登录!");
    return;
}

异常处理,连接如果断开的话直接结束程序

数据结构

这个HashMap的key使用的是Button上的人名,例如第一个Button的人名是“hhb”,那么key就是“hhb”

value是一个Message的ArrayList,里面储存发送和接收的信息

sendButton.addActionListener(new ActionListener() {
    @Override
    /**发送消息
     *
     */
    public void actionPerformed(ActionEvent e) {
        Date date = new Date();
        DateFormat format = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss");
        time = format.format(date); //2013-01-14
        message=textArea1.getText();
        textArea1.setText("");
        OnlineMessage onlineMessage =new OnlineMessage(time,sender,receivingEnd,message);
        if(hashMap.containsKey(onlineMessage.getReceivingEnd())){
            hashMap.get(onlineMessage.getReceivingEnd()).add(onlineMessage);
        }else{
            ArrayList<Message> arrayList = new ArrayList<>();
            arrayList.add(onlineMessage);
            hashMap.put(onlineMessage.getReceivingEnd(),arrayList);
        }

        showTextArea.append("我:"+message+"("+time+")"+"\n");
        try {
            UserController.sendMessage(onlineMessage);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
});

每次点击发送按钮就会将发送的信息存储到HashMap,检测是否HashMap里是否包含了这个Button人名这个key的value,如果有的话,直接将OnlineMessage添加到ArrayList,没有就创建一个ArrayList ,使用HashMap.put(key,value)添加,然后调用UserController.sendMessage将OnlineMessage发送给服务器

public static void returnOfflineMessage(ArrayList<OfflineMessage> offlineMessages) {
    for (OfflineMessage o : offlineMessages) {
        if (hashMap.containsKey(o.getSender())) {
            hashMap.get(o.getSender()).add(o);
        } else {
            ArrayList<Message> messageArrayList = new ArrayList<>();
            messageArrayList.add(o);
            hashMap.put(o.getSender(), messageArrayList);
        }
    }
}

public static void returnOnlineMessage(OnlineMessage onlineMessage) {
    if(onlineMessage.getSender().equals(receivingEnd)){
        //打印到屏幕
        showTextArea.append(onlineMessage.getSender() + " :" + onlineMessage.getMessage() + "(" + onlineMessage.getTime() + ")" + "\n");
    }else{
        changeButton(onlineMessage);
    }
    if(hashMap.containsKey(onlineMessage.getSender())){
        hashMap.get(onlineMessage.getSender()).add(onlineMessage);
    }else{
        ArrayList<Message> tempList = new ArrayList<>();
        tempList.add(onlineMessage);
        hashMap.put(onlineMessage.getSender(),tempList);
    }
}

将这两个方法放在一起说,这两个很相似,只是获得变量类型不同,工作流程稍微不同,returnOfflineMessage,不需要检测是否这个按钮是否被点击,因为信息是传进来之后才有Button,而returnOnlineMessage需要检测按钮是否被点击,当被点击的时候直接将得到的信息添加到对话框,没有被点击的话Button变红。

离线消息,Button未被点击

点击之后

在线消息

按钮未被点击状态

点击之后

showRecord.addActionListener(new ActionListener() {
            @Override
            /**展示聊天记录
             *
             */
            public void actionPerformed(ActionEvent e) {
                try {
                    UserController.requestHistoryMessage();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }

            }
        });

public static void returnHistoryList(ArrayList<HistoryMessage> list){
    hashMap.clear();
    for (Message m:list) {
        if(m.getSender().equals(sender)){
            if(hashMap.containsKey(m.getReceivingEnd())){
                hashMap.get(m.getReceivingEnd()).add(m);
            }else{
                ArrayList<Message> tempList = new ArrayList<>();
                tempList.add(m);
                hashMap.put(m.getReceivingEnd(),tempList);
            }
        }else{
            if(hashMap.containsKey(m.getSender())){
                hashMap.get(m.getSender()).add(m);
            }else{
                ArrayList<Message> tempList = new ArrayList<>();
                tempList.add(m);
                hashMap.put(m.getSender(),tempList);
            }
        }
    }
    showTextArea.setText("");
    if(receivingEnd!=null){
        for (Message M : hashMap.get(receivingEnd)) {
            if(M.getSender().equals(sender)){
                showTextArea.append("我" + " :" + M.getMessage() + "(" + M.getTime() + ")" + "\n");
            }else {
                showTextArea.append(M.getSender() + " :" + M.getMessage() + "(" + M.getTime() + ")" + "\n");
            }
        }
    }


}

获取离线消息,当点击聊天记录按钮之后,将返回登录账号的所有聊天记录,例如我登陆了“whj”这个账号

点击聊天记录这个按钮,服务端会把“whj”这张表的所有聊天记录发给客户端

然后通过returnHistoryList这个方法,对获取到的信息存入HashMap,当然存入之前会将HashMap清空一次,不然会打乱显示消息记录的顺序,然后将存好的HashMap显示出来

总结:

本次课程设计最难忘的大概就是当信息被成功转发并且在对方客户端显示的那一刻,从无到有的这个过程真的挺难的,在网上找了许多的参考代码,但其实没有一个是符合我们这种设计思路的,所以要按照我们自己这个思路自己搭框架自己设计逻辑还是挺麻烦的,我们这次设计花了4天的时间,在第二天下午的时候我们发现按照原先的框架已经写不下去了,那个时候说实话我压力还是挺大的,因为我是整个组的组长,框架和逻辑都是我设计的,如果写出来运行不了那就是我的锅了,说不定还会导致这次整个组的不合格,所以第三天早上我把代码进行重构了一次,进行的结构优化和逻辑优化,然后按照这个设计思路写了下去,成功的将任务完成了。

通过这次课程设计,让我对Java socket和Java 多线程有了更深刻的了解,提高了自己对于开发Java程序的能力,还顺带了解了数据库、云服务器、Java swing、Git

作为组长,在这次的课程设计中提高了与别人交流的能力,特别是对于开发上的专用术语有了更深的了解,当然这些都离不开我的组员对我的信任,能够敢在最后两三天重构代码,都是他们信任我的结果。

Guess you like

Origin www.cnblogs.com/haijie-wrangler/p/12169398.html