基于socket的即时通信系统的设计与实现

前言

这是学校实训时候我做的一个小项目,主要使用的就是Java的Socket技术。当时对面向对象、计算机网络等知识了解的还不深入,遇到不懂的也是看视频、查资料去解决。虽然最后完成了项目,但是感觉不是很满意,并且一直以来想对项目进行优化,然而事实上我现在就已经看不太懂当时写的东西了。所以暂时先就这样吧。这个项目最大的问题就是文件的存储,当时想的很简单,所以有很多问题,有时间再改吧(什么时候有时间呢?(滑稽))

1 系统需求分析

1.1 产品非功能需求

1.1.1 用户需求

系统的设计建立在用户的需求之上,通过对用户需求的分析,可以更好的实现系统,明确系统的设计方向。

随着互联网的不断发展,人与人之间的交流也逐渐开始越来越依赖网络,在这种形势下,我们开发出了这款即时通信系统。本着用户至上的原则,我们对用户需求进行了分析调研。结果显示,用户除了对基本的通信功能的要求外,还希望能够拥有个性化的展示,同时希望能和好友进行更多的交互。基于用户的需求,我们将软件的功能大致划分为:通信,文件传送,界面展示,天气预报等。

1.1.2 易用性需求

本产品采用javafx技术,为用户设计了简单易用的界面,同时使用css对界面进行了美化,为用户提供了良好的使用界面。在使用过程中如果用户误操作也会对用户进行相应的提示。

1.1.3 性能需求

本产品在保持界面的美观的同时为优化性能设计了具体的算法,尽量为用户提供及时的响应。

1.1.4 可维护性和可扩展性需求

本产品使用Java作为主要的开发语言,在设计的时候使用了很多Java经典的设计模式,例如:观察者模式,装饰器模式,适配器模式,单例模式,中介者模式等。这些经典的设计模式的使用极大的提高了程序的可维护性,在设计数据库表时也充分考虑了程序将来的扩展。

1.1.5 安全性需求

本产品在设计时采用正则表达式对用户输入进行过滤,同时使用了较为可靠的sql连接、查询方式。为了避免用户破坏数据库,对数据库的连接信息写入到了xml配置文件当中。

1.2 产品功能需求

1.2.1 登录功能

用户在输入账号后,客户端向服务端发送请求完成以下两个功能:

(1)如果账号正确则先从数据库中取出该账号对应的用户头像并将其显示在指定的位置。

(2)如果账号信息不正确,则头像为默认头像。

(3)点击登录,如果账号和密码都正确则进入主界面,如果其中有一项错误则直接弹出提示框,提示错误。

1.2.2 注册功能

注册功能允许用户通过网页注册相应的账号,注册时可以对个人基本信息进行填写,注册成功后将用户信息添加进数据库中。

1.2.3 添加好友功能

添加好友功能允许用户向好友发出好友申请,好友申请具有以下功能:

(1)向好友发出好友申请信息。

(2)当收到好友的好友申请时,可以在界面中显示好友申请信息,包括申请者的昵称等,并可以将好友加入任意的分组中。

(3)同意添加好友后,列表即可更新,新添加的好友就会显示在好友列表相应的分组中。同时好友在添加好友后列表也会进行相应的更新。

(4)可以在网络上查找好友,如果好友存在则显示好友的昵称和头像,如果输入的账号不符合规定会有相应的提示,如果不存在也会有对用的提示信息。

1.2.4 好友上线提示功能

主界面初始化时,好友列表中不在线的好友头像为灰色,同时点击头像无法进入聊天界面,但是可以查看好友信息。当有好友上线时,灰色头像的好友就会自动变换状态,颜色也会变为彩色。

1.2.5 天气预报功能

天气预报功能提供给用户一天内的天气情况,功能包括:

(1)根据天气情况显示相应的天气图案。

(2)鼠标悬停在天气图案上时可以出现具体的天气信息,包括温度,风向,穿衣指数,穿衣建议等。

1.2.6 删除好友功能

在好友列表中选中要删除的好友,点击鼠标右键,在弹出的菜单中点击删除好友即可将好友从好友列表中删除,同时好友信息也将从数据库中被删除。

1.2.7 黑名单功能

在好友列表中选中要加入黑名单的好友,点击鼠标右键,在弹出的菜单中点击加入黑名单,即可将好友从好友列表原先的分组中移入黑名单,同时好友信息也将从数据库中被修改。如果列表中没有黑名单分组,系统会自动创建黑名单分组。

1.2.8 查看个人信息功能

点击主界面中显示的头像即可进入个人信息查看界面,在个人信息界面中,有以下几个功能:

(1)个性背景展示。

(2)点击随机切换个性背景。

(3)个人详细信息展示。

(4)照片墙功能。

1.2.9 修改个人信息功能

进入个人信息界面后可以在右侧第一行看到编辑信息几个蓝色的字,点击即可进入个人信息编辑界面。修改个人信息功能提供给用户修改基本的个人信息的权利。在个人信息编辑界面,用户既可以对单个个人信息进行修改,也可以对多个个人信息进行修改。信息修改后数据库中相应的信息也会被修改。

1.2.10 查看好友基本信息功能

在好友列表中选中要查看个人信息的好友,右键点击即可弹出菜单,在菜单中点击查看好友信息即可进入好友信息查看界面。该界面展示了好友的基本信息,以及个性背景和照片墙等。

1.2.11 单聊功能

点击在线好友进入聊天界面即可开始一对一聊天,同时可以支持一对多聊天功能,即一个人同时和多个人进行聊天。单聊界面中可以展示自己的qq秀。

1.2.12 群聊功能

点击列表中的群组即可进入群组并开始和其它在同一群组的用户聊天。同时鼠标悬停在群组头像上可以展示群关系,群基本信息。群聊界面中也会展示群组中的用户以及个人的qq秀。

1.2.13 文字聊天功能

即时通信系统支持文字聊天功能,同时可以根据需求选择个性化的字体样式包括:字体大小、字体颜色、字体类型、粗体、斜体等。但是需要注意的是,由于系统限制,中文字体无法展示斜体样式。

1.2.14 图片聊天功能

在聊天过程中可以选择本地图片发送给好友,但是图片大小经过算法处理会被压缩。

1.2.15 图片查看器功能

由于图片在传输过程中会被压缩,因此在即使通信系统中简单实现了一个图片查看器,在接收到图片后双击图片即可打开图片查看器,图片查看器主要包括以下几个功能:

(1)将图片放大。

(2)将图片缩小。

(3)旋转图片。

1.2.16 文件传输功能

用户可以选择本机的文件发送给好友,好友在接收到文件后可以选则接受文件,好友在点击接受文件后,进度条开始运行,文件下载完成后会出现相应的提示。由于使用的是单线程实现,所以整体的下载速度并不理想。

2 系统设计

2.1 可行性分析

2.1.1 调查分析

系统的初步调查是系统设计的规划阶段的第一项活动,也是整个系统开发的第一项活动,主要目标就是了解组织机构、工作现状。

通过对整个即时通信系统业务的了解,主要业务逻辑是用户的各种操作,用户的操作经由服务器进行处理,服务器根据事先约定的通信协议对用户的各种请求进行相应的处理,然后将处理结果转发给相应的用户(包括自身)。用户的操作主要有以下几点

(1)登录。

(2)注册。

(3)聊天。

(4)发送文件、图片。

(5)添加好友、好友申请。

(6)对好友的各种操作。

(7)对自己信息的各种操作。

(8)好友以及本人对信息的展示。

(9)查看图片等信息。

总之,必须对现行系统进行详尽调查,明确用户需求,保证开发的新系统的功能与用户的要求相吻合,避免耗费大量的人力、物力、财力。

2.1.2 必要性分析

随着网络的快速发展,网络已经与我们的日常生活紧密关联在了一起。网络的及时性不仅为我们阅读信息提供了方便,也为亲朋好友间的交流提供了方便。之前相隔万里的好友,现在通过网络便可以随时发起沟通。而这种便利正有赖于即使聊天系统,即时聊天系统的应用前景和发展前景都十分客观,市场需求也很大。因此,设计一款方便用户使用的即时聊天系统是很有必要的。

2.2 数据库设计

本系统数据库主要设计了四张表,分别是:person表、friendlist表、grouplist表、grouprelation表。数据库表设计具体如图2-1所示。
在这里插入图片描述

​ 图2-1数据库表设计

person表用来存储用户的基本信息,用户的各种个人信息都存在这张表上。person表的具体设计如图2-2所示。

在这里插入图片描述
​ 图2-2 person表设计

grouplist表用来存储群组的基本信息,群组的各种信息都存在这张表上。person表的具体设计如图2-3所示。
在这里插入图片描述
​ 图2-3 grouplist表设计

friendlist表用来存储好友以及好友之间的关系,同时为了简化业务逻辑,将黑名单也加入到了好友关系中,因此不再单独设置关系表以及黑名单表。以后如果业务逻辑变复杂之后可以再进行扩展。friendlist表的具体设计如图2-4所示。 在这里插入图片描述
​ 图2-4 friendlist表设计

grouprelation表用来存群员、群关系以及群分组等信息。grouprelation表的具体设计如图2-5所示。 在这里插入图片描述

​ 图2-5 grouprelation表设计

同时,为了确保数据的安全以及数据的完整,在设计数据库表时使用了外键来确保表的完整性约束。数据库的架构设计如图2-6所示。

​ 图2-6数据库架构设计

2.3 项目结构设计

为了产品的可维护性以及可扩展性需求,本项目采用了经典的MVC模式,尽量做到界面和业务逻辑分层。同时项目采用对象流的方式进行数据交换,因此在客户端和服务器端都设置了一个相同的common包,common包主要存放两个类:Message类和User类,以及一个接口:ChatType接口。User类用来做登录前的交互,Message类用来存放用户交互的各类数据,以及用来将数据库中的数据封装成JavaBean对象。view包用来存放界面设计的相关类,同时在服务器端为了简化操作只对界面进行了很简单的设计,在客户端则采用javafx技术对主要的应用界面进行了设计。客户端view包中主要包含以下几个界面类:AddFriend类(查找、添加好友)、Chat(聊天界面)、FriendList(主界面,好友列表,群列表等)、GlobalMenu(右键菜单)、LabelMenu(右键菜单)、Login(登录)、Modify(查看信息)、ModifySelf(修改信息)、ViewPort(图片查看器)。客户端model包存放登陆前的主要业务逻辑的实现相关的类),服务端则包含业务逻辑的实现相关的类,同时服务端model包内也含有数据库业务逻辑实现的相关类。而客户端登录后的业务逻辑实现相关的类暂存在tools包内,服务器端的tools包内则主要包含连接数据库的工具类,以及其它的一些工具类。同时为了实现天气预报功能,客户端新建了一个juheAPI的包,包内主要存放聚合数据网提供的API的相关实现的类以及接口。具体的项目结构如图2-7。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9trApLSn-1606738457588)(C:Userswu2weAppDataRoamingTypora	ypora-user-imagesimage-20201130195703630.png)]
在这里插入图片描述

​ 图2-7项目结构设计

2.4 设计模式

为了项目的维护性以及可扩展性,本项目采用了一些Java经典的设计模式:观察者模式,中介者模式,单例模式,装饰器模式等。

单例模式主要用在界面设计上,例如在设计右键菜单时就可以使用单例设计模式,这样可以提高程序的工作效率,同时也体现了面向对象的思想。同时在各个界面的设计上也都可以体现出单例设计模式的思想。

装饰器模式时Java基础类库中IO包下各个类和接口的基本设计思想。装饰器模式综合运用了Java面向对象的思想:继承、多态进行设计,体现出Java面向对象思想的强大。本项目大量使用IO流,因此对装饰器模式的基本了解是必不可少的。

观察者模式主要运用在一些设计广播的业务逻辑中,例如好友上线提醒功能就体现出观察者模式的强大,在一个用户登录时就通过广播的形式通知其它观察者有一个用户上线了,然后其他用户就会对此做出相应的动作。

中介者模式主要用在客户端与服务端的交互上,服务器端作为中介者转发其他用户的信息,并处理客户端发过来的请求,返回给发起请求的客户端。

总之,一个好的系统离不开设计模式的使用,本项目采用了一些经典的设计模式,正是为了提高程序的可读性、可维护性、可拓展性,以便为用户提供更好的体验。

2.5 通信协议设计

为了各个客户端和服务器交互时信息类型的统一性,在项目设计过程中必须实现一个统一的通信协议。该通信协议的目的是为了方便客户端之间的数据交互,类似于一种“暗号”。为了方便通信协议的使用,可以将各种信息封装在ChatType接口中,这样既方便使用也方便系统的维护和拓展。具体的设计如图2-8所示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Nw3o0VKj-1606738457590)(C:Userswu2weAppDataRoamingTypora	ypora-user-imagesimage-20201130195804016.png)]

​ 图2-8 通信协议设计

2.6 系统总体功能设计

本项目为即时通信系统,根据对用户需求的分析,设计主要功能模板如下图2-9所示。

在这里插入图片描述

​ 图2-9 系统总体功能设计

用户用例图建模如图2-10所示。

在这里插入图片描述

​ 图2-10 用户用例图建模

3 系统实现

3.1 登录功能

本项目采用客户端/服务器端架构(C/S架构),用户发送的请求都将传送到服务器端进行处理。服务器端包括数据库以及服务端后台软件。在用户输入账号和密码信息后,客户端通过对象流的方式向服务端发送一次请求,这是的链接是一次性的链接,服务端在接受到这个请求后就通过事先实现的相关协议对请求进行处理。处理完成后服务器端在将处理结果返还给客户端发起请求的用户。至此,一次请求结束。第一次请求主要是为了返回用户的头像,服务器端只对账号信息进行比对,如果账号信息可以在数据库中查找到就返回该账号对应的头像信息并显示。在登录时再次向服务器端发起一次请求,这次请求需要服务器端同时比对账号和密码两个信息。如果两个信息都符合则根据通信协议返回相应的结果。这两次请求都是一次性的请求,都是在相应的事件被触发后才进行的实现。在登录成功后,在客户端开一个线程和服务器端保持通信。系统登录界面如图3-1所示。

在这里插入图片描述

​ 图3-1 登录界面

3.2 添加好友

添加好友需要先查找好友,在登陆后客户端与服务端已经建立了持久的联系,因此在添加好友时先向服务器端发送一个查找好友的请求,服务器端收到请求后通过通信协议对请求内容进行判断,然后根据对应的请求进行数据库操作,从数据库中获得要查找的好友的信息,然后将信息返还给发起请求的一方。请求方接收到信息后通过通信协议的内容对返回的信息进行处理,最终显示好友信息或者相应的错误提示。在用户输入时,为了避免用户的误操作,需要使用正则表达式对用户的输入进行过滤。在好友信息显示后用户既可以添加好友到指定的好友分组中。但是如果是检索自己的账号,只会显示自己的信息,不能对自己进行添加操作。

查找好友信息界面如图3-2所示。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BEJa0MgZ-1606738457591)(C:Userswu2weAppDataRoamingTypora	ypora-user-imagesimage-20201130200204813.png)]

​ 图3-2 查找好友

添加好友的操作如图3-3、3-4和3-5所示。

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

​ 图3-3 添加好友前列表

在这里插入图片描述

​ 图3-4 好友接收到添加请求

在这里插入图片描述

​ 图3-5 添加好友后列表

3.3 天气预报

天气预报功能是通过解析聚合数据网提供的API返回的json串来完成的,具体的功能有一天天气预报,穿衣指数,穿衣建议,温度等。天气预报功能如图3-6所示。

在这里插入图片描述

​ 图3-6 天气预报

由于具体的天气情况的展示使用了提示框的形式,因此界面无法截图,故不在进行展示。

3.4 查看信息

查看信息包括查看好友信息以及查看个人信息,这两个功能实现起来类似,但是由于触发事件不同,因此也比较难把握,个人信息查看主要是鼠标点击事件而好友信息查看则使用了右键菜单,右键菜单总共有三个功能:查看信息(好友信息)、删除好友、黑名单。事件触发后会发送一个请求给服务器端,服务器端得到请求后根据通信协议对请求进行处理,并将处理的结果发送给请求端。最终在界面展示相应的内容。

查看个人信息界面如图3-7所示。

在这里插入图片描述

​ 图3-7 个人信息查看

查看好友信息如图3-8所示。

在这里插入图片描述

​ 图3-8 好友信息查看

3.5 编辑信息

编辑信息可以对自己的信息进行修改,同时可以修改头像。在修改信息时用户可能只想修改几条信息,这时我们可以在初始化编辑信息界面时将旧的数据填充在文本框内,这样就可以节省很多的麻烦。编辑信息在服务器端体现为数据库的修改操作,本身没有什么难度,但是考虑到界面的信息是时时更新的,因此实现起来并不是特别的简单,在实现过程中充分体现了面向对象的思想。

修改头像操作如图3-9和3-10所示。

在这里插入图片描述

​ 图3-9 头像修改前

在这里插入图片描述

​ 图3-10 头像修改后

编辑个人信息界面如图3-11所示。

在这里插入图片描述

​ 图3-11 个人信息编辑

3.6 文字聊天

本项目支持简单的文字聊天。聊天界面启动时将用户名与好友的名字进行组合形成一个唯一的id标识,然后将聊天界面和id放入HashMap中,在发送文字信息时,客户端向服务端发送请求,服务端在接受到请求后将消息转发给好友或者群聊界面。消息的展示则通过对界面的时时更新来完成。在接受到服务器端发来的信息后通过取出发送者和接收者组成一个唯一标识,从而从map中取出存的界面,然后调用相应的方法即可显示消息。这也体现了面向对象的特性。文字聊天界面如图3-12所示。

在这里插入图片描述

​ 图3-12 文字聊天

3.7 图片聊天

图片聊天是文件传输的一种体现,客户端读取本地文件并通过字节数组流将文件转换为字节数组进行传输。服务器将信息转发给相应的客户端即可。具体的效果如图3-13所示。

在这里插入图片描述

​ 图3-13 图片聊天

3.8 文件传输

文件传输是在图片传输的基础上完成的,同样是通过传输字节数组来完成的,具体的完成效果如图3-14所示。

在这里插入图片描述

​ 图3-14 文件传输

3.9 文字样式选择

文字选择功能是在文字聊天的基础上完成的,在文字聊天发送数据包的同时在数据包中同时将各种字体的设置样式转换为字符串并发送给服务端,服务端在对消息进行转发。在设置文字样式时使用了几种不同的方式,一种是javafx特有的setStyle方法。由于Java的限制,在设置粗体和斜体时对中文字体不起作用,具体原因未知。具体的效果如图3-15所示。

在这里插入图片描述

​ 图3-15 文字样式选择

4 实训感想

本次实训的课题是设计一个即时通讯系统。在结束了Java基础内容的学习以后做这个项目还是有点吃力,但是通过这个项目也确实学到了很多的知识。对Java的网络编程、多线程、集合、IO流都进行了复习。总体来说本项目作为阶段性的实训项目很合适,基本将Java的基础知识串了起来。

做这个项目更大的收获是对于面向对象思想的理解。学习Java的过程中很容易形成一个不好的思维:单纯的将Java的优点理解为随时调用的方法和丰富的类库。这些自然是Java的强大之处,但是面向对象的思想才是项目设计过程中不可或缺的制胜法宝。面向对象必须要理解对象的作用,对象该做什么,是设计类时的难点。什么方法就应该在什么类中,什么对象就应该做什么样的事情。比如,在设计界面时业务层的类中能直接写更新界面的方法吗?显然是不能的。因为界面更新的方法应该是界面相关的类提供的,而不是业务逻辑的相关实现类该做的。总之,熟练掌握面向对象的程序设计思想是一个Java工程师应该具备的基本技能。面向对象思想可以极大的简化代码数量以及降低业务逻辑的复杂度。学习使用面向对象的思想解决问题也是后续学习的基础。因此,在学习Java的过程中一定要把握住面向对象思想的掌握。

同时,这个项目也涉及到了一些通信相关的知识。这也说明计算机的基础知识对今后的编程学习是有很大的帮助的。因此一定要重视计算机的基本知识。同时也要重视数据结构以及算法,在做项目的过程中,正是因为数据结构和算法功底不够,所以无法实现更高效的算法。

总之,通过这个项目对Java基础知识有了更深入的理解。也为后续的学习做好了铺垫。

原文地址:https://www.cnblogs.com/zwscode/p/14243897.html