5.14总结

学习通项目完成的差不多了

解决抢答问题的时候出了点问题,不知道应该怎么实现,后来新建了个socket包换了个端口专门做实时通讯,代码如下

new Thread(()->{
            try (ServerSocket realtimeServerSocket = new ServerSocket(9999)) {
                System.out.println("实时提示服务器已启动,监听端口:" + 9999);

                while (true) {
                    Socket realtimeSocket = realtimeServerSocket.accept();
                    new Thread(()-> {
                        Integer id = null;
                        try {
                            ObjectInputStream realtimein = new ObjectInputStream(realtimeSocket.getInputStream());
                            ObjectOutputStream realtimeout = new ObjectOutputStream(realtimeSocket.getOutputStream());
                            Msg now = new Msg();
                            while (true) {
                                now = (Msg) realtimein.readObject();
                                switch (now.getHappen()) {
                                    case 999:

                                        break;
                                    case 1000: // 心跳消息
                                        Integer clientId =id; // 从消息或连接中获取客户端ID
                                        lastHeartbeatTimeMap.put(clientId, System.currentTimeMillis()); // 更新最后心跳时间
                                        stringToSocketMap.put(clientId, realtimeSocket);
                                        startHeartbeatChecker();
                                        System.out.println("ok");
                                        break;
                                    case 1001:
                                        User user1 = (User) now.getData();
                                        id = user1.getId();
                                        stringToSocketMap.put(user1.getId(), realtimeSocket);
                                        idToObjectOutputStreamMap.put(user1.getId(),realtimeout);
                                        for (Integer key : stringToSocketMap.keySet()) {
                                            System.out.println("Key: " + key);
                                        }
                                        break;
                                    case 1002:
                                        Rushanswer rushanswer=(Rushanswer)now.getData();
                                        Integer classid=rushanswer.getClassid();
                                        System.out.println(classid);
                                        // 创建一个容器来存储student_id
                                        List<Integer> studentIds = new ArrayList<>();

                                        // 连接到数据库并执行查询(这里假设您已经有了一个getConnection方法)
                                        try (Connection conn = getConnection();
                                             PreparedStatement stmt = conn.prepareStatement("SELECT student_id FROM student_class WHERE class_id = ?")) {

                                            stmt.setInt(1, classid);
                                            ResultSet rs = stmt.executeQuery();

                                            // 遍历结果集,将student_id添加到容器中
                                            while (rs.next()) {
                                                studentIds.add(rs.getInt("student_id"));
                                                System.out.println(rs.getInt("student_id"));
                                            }
                                        } catch (SQLException e) {
                                            // 处理数据库查询异常
                                            e.printStackTrace();
                                        }

                                        // 遍历容器中的student_id,并找到对应的Socket发送消息
                                        for (Integer studentId : studentIds) {
                                            Socket targetSocket = stringToSocketMap.get(studentId);
                                            //System.out.println("87");
                                            if (targetSocket != null && !targetSocket.isClosed()) {
//                                                try (ObjectOutputStream outa = new ObjectOutputStream(socket.getOutputStream())) {
//                                                    // 创建一个消息对象,设置适当的数据和happen值
                                                    Msg msg = new Msg();
                                                    // 假设您想发送rushanswer对象或者与抢答相关的其他数据
                                                    // msg.setData(...); // 设置要发送的数据
                                                    msg.setHappen(10001); // 设置适当的happen值
                                                    msg.setData(rushanswer);
                                                    System.out.println("78");
//                                                    // 发送消息
//                                                    outa.writeObject(msg);
//                                                    outa.flush();
//                                                } catch (IOException e) {
//                                                    //处理发送消息时可能出现的异常
//                                                    e.printStackTrace();
//                                                    // 可能需要从stringToSocketMap中移除该socket,因为它可能已关闭或无效
//                                                    //stringToSocketMap.remove(studentId);
//                                                }
                                                if (targetSocket == realtimeSocket) { // 确保我们不会向当前线程关联的socket发送消息(除非这是意图)
                                                    // 使用当前线程的realtimeout流发送消息
                                                    realtimeout.writeObject(msg);
                                                    realtimeout.flush();
                                                } else if (targetSocket != null && !targetSocket.isClosed()) {
                                                    // 如果需要向其他客户端发送消息,你需要有到那个客户端的OutputStream的引用
                                                    // 这通常意味着你需要维护一个到所有客户端OutputStream的映射,而不仅仅是Socket
                                                    // 在这个简化的示例中,我们假设你有这样的映射
                                                    ObjectOutputStream targetOutputStream =idToObjectOutputStreamMap.get(studentId); // 获取到targetSocket的OutputStream
                                                    targetOutputStream.writeObject(msg);
                                                    targetOutputStream.flush();
                                                }
                                            } else {
                                                // socket为null或已关闭,可以记录日志或执行其他操作
                                            }
                                        }
                                        break;
                                }
                            }
                        } catch (IOException e) {
                            stringToSocketMap.remove(id);
                            throw new RuntimeException(e);
                        } catch (ClassNotFoundException e) {
                            throw new RuntimeException(e);
                        }
                    }).start();

这是服务器代码,下面是客户端代码

new Thread(()->{
                try {
                    clientSocket1 = new Socket("localhost", 9999);
                    outnow = new ObjectOutputStream(clientSocket1.getOutputStream());
                    innow = new ObjectInputStream(clientSocket1.getInputStream());
                    RushanswerController.setin(innow);
                    RushanswerController.setout(outnow);
                    Msg msg =new Msg();
                    msg.setHappen(1001);
                    msg.setData(DengluController.alluser);
                    outnow.writeObject(msg);
                    outnow.flush();
                    Timer heartbeatTimer = new Timer();
                    heartbeatTimer.scheduleAtFixedRate(new TimerTask() {
                        @Override
                        public void run() {
                            try {
                                // 发送心跳消息
                                Msg heartbeatMsg = new Msg();
                                heartbeatMsg.setHappen(1000); // 心跳消息的happen值
                                outnow.writeObject(heartbeatMsg);
                                outnow.flush();
                            } catch (IOException e) {
                                // 处理异常,可能是连接已关闭
                                e.printStackTrace();
                                // 停止心跳定时器并尝试重新连接服务器
                                heartbeatTimer.cancel();
                                // ... 重新连接逻辑 ...
                            }
                        }
                    }, 0, 10 * 1000); // 立即开始,然后每隔HEARTBEAT_INTERVAL秒发送一次心跳
                    while (true) { // 持续监听服务器消息
                        msg = (Msg) innow.readObject(); // 读取消息
                        switch (msg.getHappen()) {
                            case 10001: // 假设这是表示抢答开始的响应消息类型
                                System.out.println("sdfhukis");

                                break;
                            case 10002: // 其他消息类型...
                                // 处理其他消息...
                                break;
                            // ... 其他case语句处理其他消息类型 ...
                            default:
                                // 处理未知消息类型或错误情况
                                break;
                        }
                    }
                } catch (IOException | ClassNotFoundException e) {
                    // 处理异常,例如连接断开或消息格式错误
                    e.printStackTrace();
                    // 可能需要重新连接服务器或执行其他恢复操作
                }
            }).start();

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值