网络多线程开发小项目--QQ登陆聊天功能(私聊群发)

9.1.4、QQ登陆聊天功能(私聊群发)

9.1.4.1、私聊功能

1、需求说明
在这里插入图片描述
2、思路分析
在这里插入图片描述
3、代码实现
QQClient:
1)cn.com.agree.qqclient.QQView.QQView

  case "3":
       log.debug("请输入想给谁发消息(在线用户):");
       String getterId = Utility.readString(50).trim();
       log.debug("请输入想说的话:");
       content = Utility.readString(200).trim();
      //TODO 私聊bug invalid type code: AC已解决    
       messageClientService.sendMsgToOne(getterId,userId,content);                                        

2)cn.com.agree.qqclient.message.MessageClientService

 /**
     * 私聊
     * @param getterId 接收方id
     * @param senderId 发送方id
     * @param content  消息内容
     */
    public void sendMsgToOne(String getterId,String senderId,String content){
        //创建Message对象
        Message message = new Message();
        message.setMsgType(MessageType.MESSAGE_COMM_MS);//对话,普通消息
        message.setGetter(getterId);
        message.setSender(senderId);
        message.setContent(content);
        message.setSendTime(new Date().toString());
        log.debug(senderId+" 对 "+getterId+" 说: "+content);

        //获取socket流发送message消息
        try {
            ObjectOutputStream oos = new MyObjectOutputStream(ManageClientConnectServers.getClientConnectServer(senderId).getSocket().getOutputStream());
            oos.writeObject(message);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

3)cn.com.agree.qqclient.service.ClientConnectServer

  case MessageType.MESSAGE_COMM_MS:
     log.debug(message.getSender()+" 对 "+message.getGetter()+" 说: "+message.getContent());
      break;

QQServer:
1)cn.com.agree.qqserver.service.ServerConnectClient

 case MessageType.MESSAGE_COMM_MS:
     log.debug("message:{}", message);
     log.debug(message.getSender() + " 对 " + message.getGetter() + " 说: " + message.getContent());
     //转发消息
     ObjectOutputStream oos2 = new MyObjectOutputStream(ManageServerConnectClient.getServerConnectClient(message.getGetter()).getSocket().getOutputStream());
     oos2.writeObject(message);//如果用户不在线,可以保存到数据库做离线转发
     break;

4、运行效果
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

9.1.4.2、群发功能

1、需求说明
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/8c3f9b545d4c4dffb16e9b5e3d9642ae.p

2、思路分析
在这里插入图片描述
3、代码实现
Common:
cn.com.agree.qqcommon.MessageType

String MESSAGE_ONLINEAll_MS="7";//群发消息

QQClient:
1)cn.com.agree.qqclient.QQView.QQView

 case "2":
    //TODO 群发bug invalid type code: AC待解决
   log.debug("请输入要说的内容:");
   String content = Utility.readString(100);
   messageClientService.sendMsgToAll(userId,content);
   // System.out.println("群发消息");
   break;

2)cn.com.agree.qqclient.message.MessageClientService

 /**
     * 群发
     * @param
     * @param senderId 发送方id
     * @param content  消息内容
     */
    public void sendMsgToAll(String senderId,String content){
        //创建Message对象
        Message message = new Message();
        message.setMsgType(MessageType.MESSAGE_ONLINEAll_MS);//对话,普通消息
        message.setSender(senderId);
        message.setContent(content);
        message.setSendTime(new Date().toString());
        log.debug(senderId+" 对 "+"大家说: "+content);

        //获取socket流发送message消息
        try {
            ObjectOutputStream oos = new MyObjectOutputStream(ManageClientConnectServers.getClientConnectServer(senderId).getSocket().getOutputStream());
            oos.writeObject(message);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

3)cn.com.agree.qqclient.service.ClientConnectServer

 case MessageType.MESSAGE_ONLINEAll_MS:
    log.debug(message.getSender() + " 对 " +"大家说: " + message.getContent());
    break;

QQServer:
cn.com.agree.qqserver.service.ServerConnectClient

case MessageType.MESSAGE_ONLINEAll_MS:
                        log.debug("message:{}", message);
                        log.debug(message.getSender() + " 对 " + "大家说: " + message.getContent());
                        //遍历服务端线程集合获取非发送方的线程socket进行消息转发
                        Map<String, ServerConnectClient> hm = ManageServerConnectClient.getHm();
                        Iterator<String> userIds = hm.keySet().iterator();
                        while (userIds.hasNext()) {
                            String userId = userIds.next().toString();
                            if (!userId.equals(message.getSender())) {//获取非发送方的用户id
                                ServerConnectClient serverConnectClient = hm.get(userId);
                                //获取socket进行消息转发
                                ObjectOutputStream oos3 = new MyObjectOutputStream(serverConnectClient.getSocket().getOutputStream());
                                oos3.writeObject(message);

                            }
                        }
                        break;

4、运行结果
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
注意:上述 invalid type code: AC异常
分析:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

解决
在这里插入图片描述
第三种解决方案代码
cn.com.agree.stream.MyObjectInputStream

package cn.com.agree.stream;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;

/**
 * @author 
 * @version 1.0
 * @ClassName MyObjectInputStream
 * @Description TODO 类描述
 * @date 2024/1/11  2:11 下午
 **/
public class MyObjectInputStream extends ObjectInputStream {
    public MyObjectInputStream(InputStream in) throws IOException {
        super(in);
    }

    @Override
    protected void readStreamHeader() throws IOException {
        //重写读取头部信息方法:什么也不做
    }

}

cn.com.agree.stream.MyObjectOutputStream

package cn.com.agree.stream;

import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;

/**
 * @author 
 * @version 1.0
 * @ClassName AppendObjectOutputStream
 * @Description TODO 类描述
 * @date 2024/1/11  9:46 上午
 **/
public class MyObjectOutputStream extends ObjectOutputStream {

    public MyObjectOutputStream(OutputStream out) throws IOException {
        super(out);
    }

    @Override
    protected void writeStreamHeader() throws IOException {
        //重写读取头部信息方法:不写入头部信息
        super.reset();
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值