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、需求说明
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();
}
}