多用户即时通讯系统03

4.编码实现02

4.4功能实现-私聊功能实现

4.4.1思路分析

  • 客户端 - 发送者:

    • 用户在控制台输入信息,客户端接收内容
    • 将消息构建成Messgae对象,通过对应的socket发送给服务器
  • 服务器:
    • 可以读取到客户端(发送者)发送给某个用户(接收者)的消息
    • 从管理线程的集合中,根据messgae对象的信息,获取到接收者的userId,从而获取接收者的socket
    • 最后将Message对象转发给指定客户(接收者)
  • 客户端 - 接收者:
    • 在接收者的线程(通信线程中),读取到发送者的message消息,并显示即可

4.4.2代码实现

1.客户端
1.MessageClientService类

这里新建一个类,专门用来管理聊天(私聊/群聊)的功能

package qqclient.service;

import qqcommon.Message;
import qqcommon.MessageType; import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.Date; /**
* @author 李
* @version 1.0
* 该类提供和消息(私聊、群聊)相关的服务方法
*/
public class MessageClientService { /**
* @param content 内容
* @param senderId 发送用户id
* @param getterId 接收用户id
*/
public void sendMessageToOne(String content, String senderId, String getterId) {
//构建 message
Message message = new Message();
message.setMesType(MessageType.MESSAGE_COMM_MES);//设置消息类型是普通的聊天类型
message.setSender(senderId);
message.setGetter(getterId);
message.setContent(content);
message.setSendTime(new Date().toString());//发送时间也封装到message对象中
System.out.println(senderId + " 对 " + getterId + " 说 " + content); //发送给服务端
try {//在管理线程的集合中,通过userId来获取线程,通过线程来获取对应的socket,再通过socket获取输出流
ObjectOutputStream oos =
new ObjectOutputStream(ManageClientConnectServerThread.getClientConnectServerThread(senderId).getSocket().getOutputStream());
oos.writeObject(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
2.修改:ClientConnectServerThread类

在该类的run方法中修改业务代码,增加else if语句

else if (message.getMesType().equals(MessageType.MESSAGE_COMM_MES)) {
//接收到的是普通的聊天消息
//就把服务器转发的消息,显示到控制台即可
System.out.println(message.getSendTime() + "\n" + message.getSender()
+ " 对" + message.getGetter() + " 说" + message.getContent());
}

3.修改处:QQView类
  1. 在类中增加属性messageClientService
private MessageClientService messageClientService = new MessageClientService();//该对象用于私聊/群聊
  1. 在类中的内层循环中调用messageClientService对象中的方法

case "3":
System.out.println("请输入想聊天的用户号(在线):");
String getterId = Utility.readString(50);
System.out.println("请输入想说的话:(100个字符以内)");
String content = Utility.readString(100);
//编写一个方法,将消息发送给服务端
messageClientService.sendMessageToOne(content,userId,getterId);
break;
2.服务端:
1.修改:ServerConnectClientThread类
  1. 在该类中增加方法getSocket()
public Socket getSocket() {
return socket;
}
  1. 在该类中的run方法中增加私聊的业务代码
 else if (message.getMesType().equals(MessageType.MESSAGE_COMM_MES)) {
//业务三:客户请求和某用户私聊
//根据message获取getterId,再得到接收者对应的线程
ServerConnectClientThread serverConnectClientThread =
ManageClientThreads.getServerConnectClientThread(message.getGetter());
//得到对应的socket的输出流,将message转发给指定的用户
ObjectOutputStream oos =
new ObjectOutputStream(serverConnectClientThread.getSocket().getOutputStream());
oos.writeObject(message);//转发消息,提示:如果客户不在线,可以保存消息到数据库,实现离线留言 }

运行:

2.客户端:登录三个用户菩提老祖、至尊宝、紫霞仙子,使其相互通信:

用户1:


用户2:


用户3:

day03-3私聊功能的更多相关文章

  1. WUSTOJ的“讨论”和“私聊”功能如何使用

    反正我是过了1年多才知道有讨论这个功能,2年多才知道有私聊功能. 不知道大家都是什么时候发现的... 讨论还好,在FAQ界面的下边有提示,但是私聊我真没看到哪儿有提示...是我不小心点进去的. 讨论功 ...

  2. 第二个 SignalR,可以私聊的聊天室

    一.简介 上一次,我们写了个简单的聊天室,接下来,我们来整一个可以私聊的聊天室. SignalR 官方 API 文档 需求简单分析: 1.私聊功能,那么要记录用户名或用户ID,用于发送消息. 2.怎么 ...

  3. Vue3 + Socket.io + Knex + TypeScript 实现可以私聊的聊天室

    前言 下文只在介绍实现的核心代码,没有涉及到具体的实现细节,如果感兴趣可以往下看,在文章最后贴上了仓库地址.项目采用前后端模式,前端使用 Vite + Vue3 + TS:后端使用 Knex + Ex ...

  4. ios项目里扒出来的json文件

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Menlo; color: #000000 } p.p2 { margin: 0.0px 0. ...

  5. ASP.NET程序开发范例宝典

    在整理资料时发现一些非常有用的资料源码尤其是初学者,大部分是平时用到的知识点,可以参考其实现方法,分享给大家学习,但请不要用于商业用途. 如果对你有用请多多推荐给其他人分享. 点击对应章节标题下载本章 ...

  6. iOS超全开源框架、项目和学习资料汇总(5)AppleWatch、经典博客、三方开源总结篇

    完整项目 v2ex – v2ex 的客户端,新闻.论坛.apps-ios-wikipedia – apps-ios-wikipedia 客户端.jetstream-ios – 一款 Uber 的 MV ...

  7. Github上关于iOS的各种开源项目集合(强烈建议大家收藏,查看,总有一款你需要)

    下拉刷新 EGOTableViewPullRefresh - 最早的下拉刷新控件. SVPullToRefresh - 下拉刷新控件. MJRefresh - 仅需一行代码就可以为UITableVie ...

  8. iOS及Mac开源项目和学习资料【超级全面】

    UI 下拉刷新 EGOTableViewPullRefresh – 最早的下拉刷新控件. SVPullToRefresh – 下拉刷新控件. MJRefresh – 仅需一行代码就可以为UITable ...

  9. 【转】iOS超全开源框架、项目和学习资料汇总

    iOS超全开源框架.项目和学习资料汇总(1)UI篇iOS超全开源框架.项目和学习资料汇总(2)动画篇iOS超全开源框架.项目和学习资料汇总(3)网络和Model篇iOS超全开源框架.项目和学习资料汇总 ...

随机推荐

  1. 『现学现忘』Git后悔药 — 27、版本回退介绍

    目录 1.什么版本回退 2.需要了解两个知识点 (1)HEAD是什么 (2)HEAD指针用法 3.git reflog命令介绍 1.什么版本回退 版本回退也可以叫回滚. 若修改过的文件,不仅添加到了暂 ...

  2. Django定时任务Django-crontab的使用

    在使用的django做测试平台时,,多多少少都会遇到需要定时任务的功能,比如定时执行任务,检查订单之类 的.可能是一段时间,比如每隔 10分钟执行一次,也可能是定点时间,比如 14:00 执行,也可能 ...

  3. P1087 FBI树 [2004普及]

    这是个正常的.很简单的分治,然后我成功地将这个题搞成了一个贼难搞的东西 还是说一下我那个非常麻烦的思路: 1. 建树 2. 后序遍历 然后就在建树的过程中死循环了,然后还一堆毛病 看了一个AC代码,该 ...

  4. Spring 核心概念

    Spring 核心概念 引言 本文主要介绍 Spring 源码中使用到的一些核心类 1. BeanDefinition BeanDefinition表示Bean定义,BeanDefinition 中存 ...

  5. 使用Docker搭建自己的Bitwarden密码管理服务

    相信身为开发者,总会在各种网站中注册账号,为了方面记忆可以使用同一套账号密码进行注册,自从前段时间学习通时间撞库后有些人已经开始疯狂改密码了,可是密码一多就很难记忆,最好找个地方存储账户信息 我曾经使 ...

  6. Re:用webpack从零开始的vue-cli搭建'生活'

    有了vue-cli的帮助,我们创建vue的项目非常的方便,使用vue create然后选择些需要的配置项就能自动帮我们创建配置好的webpack项目脚手架了,实在是'居家旅行'必备良药.这次借着学习w ...

  7. Hippo4J v1.3.1 发布,增加 Netty 监控上报、SpringCloud Hystrix 线程池监控等特性

    文章首发在公众号(龙台的技术笔记),之后同步到博客园和个人网站:xiaomage.info Hippo4J v1.3.1 正式发布,本次发布增加了 Netty 上传动态线程池监控数据.适配 Hystr ...

  8. nginx编译安装支持lua脚本

    一.准备编译环境 1.操作系统:CentOS7.6 2.安装编译所需安装包 yum install gcc pcre pcre-devel zlib zlib-devel openssl openss ...

  9. CentOS7设置内核启动顺序

    1.查看设备上安装了几个内核 cat /boot/grub2/grub.cfg |grep menuentry 2.查看当前内核 grub2-editenv list saved_entry=Cent ...

  10. 20220722-Java可变参数

    Java可变参数总结 来源:B站韩顺平老师的Java入门教学 代码示例如下: public void f(String str,int... nums){ 方法体; } 代码示例如下: public ...