【课程设计】Java聊天室

介绍

基于JavaFx实现聊天室,消息序列化采用fastjson。有广播与单播两中发送消息的方式。

效果图

在这里插入图片描述
在这里插入图片描述

原理图

  1. 退出
    登录流程
  2. 发送消息
    消息发送
  3. 广播
    在这里插入图片描述
  4. 登录
    在这里插入图片描述

消息类型

在这里插入图片描述
在这里插入图片描述

主要代码

while(true)
            {
                byte [] buf = new byte [1027];
                DatagramPacket packet = new DatagramPacket(buf, 1024);
                socket.receive(packet);//接受消息
                int len = packet.getLength();
                String str = new String(buf, 0, len,"UTF-8");
                System.out.println(str);
                msg.appendText(str + "\n");//在图形界面输出接受到的消息
                JSONObject jObject = JSONObject.parseObject(str);
                int type = jObject.getInteger("type");//获取消息类型
                if(type == MsgType.LOGIN){//若为登录消息,则将用户数加一作为用户ID
                    count += 1;
                    User u = new User(count, packet.getAddress(), packet.getPort());
                    login(u);//执行登录操作
                }else if(type == MsgType.UNICAST){//单播消息
                    unicast(jObject);
                }else if(type == MsgType.BROADCAST){//广播消息
                    broadcast(MsgType.BROADCAST, jObject, jObject.getInteger("from"));
                }else if(type == MsgType.LOGOUT){//用户登出
                    onlineList.removeIf(i -> i.getUid().equals(jObject.getInteger("uid")));
                    broadcast(type, jObject, jObject.getInteger("uid"));
                    msg.appendText(String.format("%d离线\n", jObject.getInteger("uid")));
                }
            }
/*
	此函数执行新用户登录的操作,即在线用户列表添加该用户,并向其他客户端广播该用户登录,给该用户客户端返回在线用户列表,参数u为新登录的用户
*/
void login(User u) throws IOException
    {
        List<Integer> list = new ArrayList<>();
        for(User uItem : onlineList){//获取所有在线用户
            list.add(uItem.getUid());
        }
        onlineList.add(u);//在线用户列表添加该用户
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("type", MsgType.ONLINE);
        jsonObject.put("online", list);
        jsonObject.put("uid", u.getUid());
        System.out.println(jsonObject.toJSONString());
        byte [] buff = jsonObject.toJSONString().getBytes("UTF-8");
        DatagramPacket dPacket = new DatagramPacket(buff, buff.length, u.getHost(), u.getPort());
        socket.send(dPacket);//给该客户端发送在线用户列表
        JSONObject logMsg = new JSONObject();
        logMsg.put("type", MsgType.LOGIN);
        logMsg.put("uid", u.getUid());
        broadcast(MsgType.LOGIN, logMsg, u.getUid());//向其他客户端广播该用户上线
        msg.appendText(String.format("%d 登录\n", u.getUid()));
}

/*
	该函数实现消息的广播,通过循环遍历除发送方外的所有在线用户并给这些用户发送消息
	参数type为消息类型
	参数jsonObject为要发送的JSON格式的消息
	参数uid为发送方的用户,给该用户不发送消息
*/
void broadcast(Integer type, JSONObject jsonObject, Integer uid) throws IOException
{
    byte [] byteMsg = jsonObject.toJSONString().getBytes("UTF-8");
    for(User u : onlineList){//遍历所有在线用户
        if(!u.getUid().equals(uid)){//若在线用户不是发送方则发送消息
            DatagramPacket dPacket = new DatagramPacket(byteMsg, byteMsg.length, u.getHost(), u.getPort());
            socket.send(dPacket);
        }
    }
}
/*
	该部分为循环接收消息,当有消息时,判断消息类型并执行相应的操作
*/
while(true)
        {
            byte [] buf = new byte[1024];
            DatagramPacket p = new DatagramPacket(buf, 1024);
            try {
                socket.receive(p);//接受数据包
                String s = new String(buf, 0, p.getLength(), StandardCharsets.UTF_8);//解码
                System.out.println(s);
                JSONObject jsonObject = JSONObject.parseObject(s);
                Integer type = jsonObject.getInteger("type");//获取消息类型
                if(type.equals(MsgType.LOGIN)){//若为登录消息,则将登录的用户加入客户端在线用户列表
                    Platform.runLater(()->{
                        addUser(jsonObject.getInteger("uid"));
                    });
                }else if(type.equals(MsgType.ONLINE)){//若为在线用户消息,则更新在线用户
                    JSONArray list = jsonObject.getJSONArray("online");
                    uid = jsonObject.getInteger("uid");
                    Platform.runLater(()->{
                        getOnlienUser(list);//该函数在线用户更新为接受到的数据包中的用户
                    });
                }else if(type.equals(MsgType.LOGOUT)){//若为登出消息,则在在线用户里删除登出的用户
                    Platform.runLater(()->{
                        rmUser(jsonObject.getInteger("uid"));//该函数移除登出的用户
                    });
                }else{//若为普通消息,则将其显示在文本框中
                    showRecMsg(jsonObject);
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

资源链接

https://download.csdn.net/download/m0_47230106/87562727

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值